by oising
12. August 2008 14:03
It’s getting harder to post useful scripting tips for PowerShell these days as there are so many talented hardcore scripting bloggers around. My day to day is job is not system/network/server administrator; I’m a .NET developer, having started the C# habit about eight or nine years ago with the early CLR 1.0 beta. So, from here on in, I’ve decided that a better direction for me to take from now on is that of a PowerShell developer, as opposed to a scripter. There are very few (if any?) dedicated PowerShell developer blogs around, and so I figured I should try to fill that gap as best I can. I have a not insignificant amount of experience writing providers, cmdlets and other widgety bits, so it’s a good time to share my experiences. Of course, my way is not “the” way, so please reply with your own experiences/advice/mocking/whatever. ;-)
That said, I am not eschewing scripting altogether – I have some stuff in the pipeline (har-har) concerning areas I’m interested in, like eventing and jobs/remoting.
by oising
6. June 2008 01:20
I took a few hours yesterday to "tidy up my room" so to speak, so I built a nice MSI installer, updated the help, CodePlex Wiki and examples and closed all bugs. This is probably the final release now that PowerShell 2.0 CTP2 has introduced support for eventing, so thanks for all the support.
New Features
- Multiple named queue support and default queue with -QueueName parameter
- Better COM support, window message pumping etc.
- NoFlush / Peek parameter support for queue reading
- Get-EventQueue command added for viewing queues and their message counts.
Cmdlet Name Changes
- Get-Event -> Read-Event
- Connect-EventListener -> Connect-Event
- Disconnect-EventListener -> Disconnect-Event
Additionally, several niggling bugs closed (including the one where read-event -wait would return immediately with no events).
http://www.codeplex.com/pseventing
For an advanced example: Foreground / Background Swappable Downloads In PowerShell.
by oising
14. December 2007 16:04
In case anyone is interested, here are my slides in PowerPoint PPTX format from the most recent PS Virtual User Group. It covers the new Path handling infrastructure for PscxCmdlets in the upcoming PowerShell Community Extensions 1.2 and some brief information on my PowerShell Eventing snap-in for PowerShell.
psvug2_oisin_grehan.zip (152 KB)
(updated to a zip: it appears DasBlog will not serve pptx files?)
by oising
5. December 2007 12:47
Here's another interesting use for my PowerShell Eventing Snap-In, where I'm simulating unix-style foreground/background tasks. In this case, the task is a large download using System.Net.WebClient. Just dot-source the script below and start a download using the Start-Download function, passing the url to the large file and the local path where to save your file (be sure to fully qualify the save path). The download will start immediately and show a progress bar with bytes remaining and a percentage, however you can hit Ctrl+C at any time and the download will continue in the background. You can get back to PowerShell tasks, and bring back up the progress bar by invoking Show-Progress at any time. Use Stop-Download to cancel the currently active download. Only one download can be active at a time, but this could easily be extended to support a pool of downloads (using multiple WebClient objects).
downloads.ps1 (1.85 KB)
-
-
- function Stop-Download {
- $wc.CancelAsync()
- }
-
- function Start-Download {
- param(
- [uri]$Url = $(throw "need Url."),
- [string]$Path = $(throw "Need save path.")
- )
-
-
- if (-not $global:wc) {
- $global:wc = New-Object System.Net.WebClient
- $var = get-variable wc
- Connect-EventListener -Variable $var `
- -EventName DownloadProgressChanged, DownloadFileCompleted
- }
-
- if ($wc.IsBusy) {
- Write-Warning "Currently busy: Please cancel current download or wait until it is completed."
- return
- }
-
- $wc.DownloadFileAsync($url, $path, $path)
- Write-Host "Download started. Ctrl+C to continue in background."
- Show-Progress
- }
-
- function Show-Progress {
- if (-not $wc.IsBusy) {
-
- get-event | Out-Null
- "No active download."
- return
- }
-
- Start-KeyHandler -CaptureCtrlC
-
- trap [exception] {
- Stop-KeyHandler
- Write-Warning "error"
- $_
- return
- }
-
- $exiting = $false
-
-
- while (-not $exiting) {
- $events = @(Get-Event -Wait)
- $event = $null;
-
-
- foreach ($event in $events) {
- if ($event.Name -eq "CtrlC") {
- break;
- }
- }
-
- switch ($event.Name) {
- "DownloadProgressChanged" {
- $r = $event.args.BytesReceived
- $t = $event.args.TotalBytesToReceive
- $activity = "Downloading $($event.args.userstate)"
- $p = [math]::Ceiling(([double]$r / $t) * 100)
- Write-Progress -Activity $activity -PercentComplete $p `
- -Status ("{0} of {1} byte(s)" -f $r,$t)
- }
- "DownloadFileCompleted" {
- Write-Progress -Activity DownloadComplete -Completed
- "Complete."
- $exiting = $true
- }
- "CtrlC" {
- "Switching to background downloading. Show-Progress to move to foreground."
- $exiting = $true
- }
- }
- }
- Stop-KeyHandler
- }
by oising
2. December 2007 21:48
Using Windows Forms controls in PowerShell is a tricky thing, because it only supports very simple event
handling. However, some time ago I wrote a Snap-In to allow anyone to work with .NET events, even asynchronous ones. You can download it from my PSEventing CodePlex project; it comes with full help via the normal PowerShell mechanisms of -? and get-help. Examples are also available online on how to use the project for more complex scenarios. Here's simple demonstration of autogenerating a listbox control filled with choices given as arguments to a simple script:
-
- $choice = .\get-choice.ps1 "one","two","three"
And here is the source to the get-choice.ps1 script itself. This requires PSEventing 1.0 or 1.1 Beta.
-
-
-
-
- param([string[]]$choices = $(throw "please supply a string array of choices"))
-
- if ($choices.length -eq 0) {
- Write-Warning "cannot be a zero length array."
- return
- }
-
-
- $form = new-object windows.forms.form
- $form.Text = "Choose..."
- $form.MinimizeBox = $false
- $form.MaximizeBox = $false
- $form.AutoSize = $true
- $form.AutoSizeMode = "GrowAndShrink"
-
-
- $listbox = new-object windows.forms.listbox
- $choices | % { [void]$listbox.items.add($_) }
-
- $form.controls.Add($listbox)
-
-
- Connect-EventListener -VariableName listbox -EventName SelectedIndexChanged -Verbose
-
-
- Connect-EventListener -VariableName form -EventName Closed -Verbose
-
- $form.Show()
-
-
- $event = Get-Event -Wait
-
-
- write-host ($event | ft -auto | out-string)
-
- $form.Dispose()
-
- $choice = $listbox.SelectedItem
-
-
- $form = $null
- $listbox = $null
-
-
- if ($event.Name -eq "SelectedIndexChanged") {
- $choice
- } else {
- $null
- }
Have fun!