Get OSD Info Post-Deployment with PowerShell

In MDT-integrated Configuration Manager, a UDI task sequence contains a couple of steps called Branding to Reg that brands OSD variables to the registry.  This can be useful for reporting, and they can be inventoried with Configuration Manager using the handy RegKeyToMOF utility.

Capture

These steps can also be added manually to a ZTI task sequence as Kenneth van Surksum describes in his blog series.

The steps run a script called “OSDBranding.vbs” which defines which variables will be stamped to the following registry location:

HKLM\Software\Microsoft\MPSD\OSD

You can edit this script to add / remove any variables you want to save in the registry.  If you have custom variables that begin with “OSD” for example, these will be saved to the registry by default.

I wrote the following PowerShell script to retrieve these OSD registry values post-deployment from any remote computer.  The script includes a calculation of the deployment duration if the OSDStartTime and OSDEndTime variables are populated and adds it as OSDDuration.  It only returns properties that actually have populated values.

Example:


Get-OSDInfo -Computername PC001

Capture
 

Get-OSDInfo


function Get-OSDInfo
{
    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory = $true,
                ValueFromPipelineByPropertyName = $true,
                ValueFromPipeline = $true,
        Position = 0)]
        [ValidateScript({
                    Test-Connection -ComputerName $_ -Count 2 -Quiet
        })]
        [string]$ComputerName
    )

    # Define code to run
    $Code = {
        $results = @()

        # Check if the registry key exists, and get the property list if it does
        try
        {
            $Properties = Get-Item -Path 'HKLM:\SOFTWARE\Microsoft\MPSD\OSD' | Select-Object -ExpandProperty Property -ErrorAction Stop
        }
        catch
        {
            Write-Host -Object "$_" -ForegroundColor Red
            continue
        }

        # Get the property values for each key
        $Properties | ForEach-Object -Process {
            $value = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\MPSD\OSD' -Name $_ | Select-Object -ExpandProperty $_
            if ($value)
            {
                $obj = New-Object -TypeName psobject
                Add-Member -InputObject $obj -Name Property -Value $_ -MemberType NoteProperty
                Add-Member -InputObject $obj -Name Value -Value $value -MemberType NoteProperty
                $results += $obj
            }
        }

        # Calculate OSD duration if start time and end time exists
        $start = $results | Where-Object -FilterScript {
            $_.Property -eq 'OSDStartTime'
        }
        $end = $results | Where-Object -FilterScript {
            $_.Property -eq 'OSDEndTime'
        }
        if (($start.Value -ne $null) -and ($end.Value -ne $null))
        {
            $Hours = (($end.Value | Get-Date) - ($start.Value | Get-Date)).Hours
            $Minutes = (($end.Value  | Get-Date) - ($start.Value | Get-Date)).Minutes
            $Duration = "$Hours hours $Minutes minutes"
            $obj = New-Object -TypeName psobject
            Add-Member -InputObject $obj -Name Property -Value 'OSDDuration' -MemberType NoteProperty
            Add-Member -InputObject $obj -Name Value -Value $Duration -MemberType NoteProperty
            $results += $obj
        }

        # Sort and return results
        $results = $results | Sort-Object -Property Property
        if ($results)
        {
            return $results
        }
    }

    # Invoke the code remotely
    try
    {
        Invoke-Command -ComputerName $ComputerName -ScriptBlock $Code -ErrorAction Stop |
        Select-Object -Property Property, Value |
        Format-Table -AutoSize
    }
    catch
    {
        Write-Host -Object "$_" -ForegroundColor Red
    }
}