PowerShell Stopwatch

In PowerShell scripts it is sometimes helpful to use a timer, for example to measure how long a certain task takes.  If you create GUI applications with PowerShell, it can be useful to display a timer during a long-running task.  It’s actually quite simple to do and there are plenty of examples for C# programmers, but not for PowerShell scripters, so I thought I would write this quick post to demonstrate how it can be done.

This example uses a WPF window to display a timer as a stopwatch application, but you can of course re-use the code for your needs.  The System.Diagnostics.Stopwatch class can be used to measure time, and the System.Windows.Forms.Timer class can be used to display the time in a GUI window via the Tick event.

GIF

 


# Load Assemblies
Add-Type -AssemblyName PresentationFramework, System.Windows.Forms


# Define XAML code
[xml]$xaml = @"
<Window 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Stopwatch" Height="273.112" Width="525" ResizeMode="CanMinimize">
    <Grid>
        <TextBox x:Name="Time" HorizontalContentAlignment="Center" IsReadOnly="True" VerticalContentAlignment="Center" FontSize="80" FontFamily="Segui" BorderThickness="0" HorizontalAlignment="Left" Margin="11,10,0,0" TextWrapping="Wrap" Text="00:00:00" VerticalAlignment="Top" Height="94" Width="496"/>
        <Button x:Name="Start" Content="Start" HorizontalAlignment="Left" FontSize="45" Background="GreenYellow" Margin="11,124,0,0" VerticalAlignment="Top" Width="154" Height="104"/>
        <Button x:Name="Stop" Content="Stop" HorizontalAlignment="Left" FontSize="45" Background="Tomato" Margin="180,124,0,0" VerticalAlignment="Top" Width="154" Height="104"/>
        <Button x:Name="Reset" Content="Reset" HorizontalAlignment="Left" FontSize="45" Background="Aquamarine" Margin="351,124,0,0" VerticalAlignment="Top" Width="154" Height="104"/>
    </Grid>
</Window>

"@

# Load XAML elements into a hash table
$script:hash = [hashtable]::Synchronized(@{})
$hash.Window = [Windows.Markup.XamlReader]::Load((New-Object -TypeName System.Xml.XmlNodeReader -ArgumentList $xaml))
$xaml.SelectNodes("//*[@*[contains(translate(name(.),'n','N'),'Name')]]") | ForEach-Object -Process {
    $hash.$($_.Name) = $hash.Window.FindName($_.Name)
}

# Create a stopwatch and a timer object
$Hash.Stopwatch = New-Object System.Diagnostics.Stopwatch
$Hash.Timer = New-Object System.Windows.Forms.Timer
    $Hash.Timer.Enabled = $true
    $Hash.Timer.Interval = 55

# Start button event
$hash.Start.Add_Click({

    $Hash.Stopwatch.Start()
    $Hash.Timer.Add_Tick({$Hash.Time.Text = "$($Hash.Stopwatch.Elapsed.Minutes.ToString("00")):$($Hash.Stopwatch.Elapsed.Seconds.ToString("00")):$($Hash.Stopwatch.Elapsed.Milliseconds.ToString("000"))"})
    $Hash.Timer.Start()
       
})

# Stop button event
$hash.Stop.Add_Click({
    
    if (!$Hash.Stopwatch.IsRunning) { return }
    $Hash.Timer.Stop()
    $Hash.Stopwatch.Stop()

})

# Reset button event
$hash.Reset.Add_Click({

    if ($Hash.Stopwatch.IsRunning) { return }
    $Hash.Stopwatch.Reset()
    $Hash.Time.Text = "00:00:00"

})

# Display Window
$null = $hash.Window.ShowDialog()

New Free App – ConfigMgr Deployment Reporter

Just released a new free application for ConfigMgr admins – ConfigMgr Deployment Reporter.  I developed this app for use in the organisation I currently work for, and it turned out quite well, so I decided to release a public version to the community!

capture

I developed this app as an alternative (and IMO easier) way to report on ConfigMgr deployments than using the ConfigMgr console. It uses a little different format than the console node allowing you to select which deployment you wish to view data for based on the “feature type” (ie application, package etc) and report on only that deployment.  It also introduces a separation of results between all applicable systems for a deployment, and only those systems which have currently reported status, which allows for a more accurate view of the success of a deployment as it progresses.

The app allows the creation of charts and HTML-format reports to give a nice graphical snapshot of a deployment.

I also added the capability to report per-device for Software Update and Task Sequence deployments.  For Software Updates, this allows you to see which updates from the deployment are applicable to the machine and the status of each update, and for Task Sequences it allows viewing the execution status of each step in the task sequence for the selected device.

As usual, I code purely in PowerShell using WPF for the UI.  This time I added metro styling using the excellent MahApps.Metro project 🙂

Download the app from here.