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
    }
}

 

 

2 thoughts on “Get OSD Info Post-Deployment with PowerShell

  1. Hey, if i want to use the “hostname” when im running the script, Tried to make $computer1=hostname
    then Get-OSDInfo -Computername $computer1

    But didnt get it to work, any tips? Thanks Pontus.

    1. Hi, try this version of the code. Simply omit the “computername” parameter to run it against the local machine.

      function Get-OSDInfo
      {
      [CmdletBinding()]
      Param
      (
      [Parameter(Mandatory = $false,
      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
      {
      If ($ComputerName)
      {
      Invoke-Command -ComputerName $ComputerName -ScriptBlock $Code -ErrorAction Stop |
      Select-Object -Property Property, Value |
      Format-Table -AutoSize
      }
      Else
      {
      Invoke-Command -ScriptBlock $Code -ErrorAction Stop |
      Select-Object -Property Property, Value |
      Format-Table -AutoSize
      }

      }
      catch
      {
      Write-Host -Object “$_” -ForegroundColor Red
      }
      }

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.