OSD Information Script for ConfigMgr

OSD Information Script for ConfigMgr

Here’s my version of an OSD information tattoo script for ConfigMgr. There are a few others out there, but I didn’t like exactly how they worked or they weren’t really production ready IMO. This version is however heavily based on the OSD Tattooer Script by Stephane van Gulick which was close to what I wanted but not quite.

This script, when run inside a task sequence, captures a handfull of variable values and writes them to either WMI, the registry, or both. WMI is usually my preference because it’s drop-dead easy to then add information from WMI to ConfigMgr hardware inventory.

In addition to the default values collected, the values of any task sequence variables prefixed by “OSDInfo_” are also collected. This prefix can be modified using a script parameter.

Additional parameters include defining the namespace, class, and ID for the information stored. The help for the script gives all the details.

Just add the script to your task sequence after the Setup Windows and ConfigMgr task using a PowerShell script task type and include the appropriate parameters. I generally add this to both my build and capture task sequences using an ID of something like “Build” and my deployment task sequences using an ID of something like “Deploy”. This then adds info for both task sequences to the registry and/or WMI.  Also, keep the IDs the same across task sequences of the same type; the differences will be reflected in the other data collected like the task sequence name.

Set-OSDInfo Version 1.1: Get it on GitHub

Script Help

22 Comments

Cancel

  1. Hi, your download link doesn’t work

  2. If the parameter -ID is empty will that result in an error? This value must be the name of the TS?

    • Yes, it will result in an error as this is a required parameter. The value of the parameter is anything you want it to be. I typically set it to Build for the build and capture TSes and Deploy for my deployment TSes.

      • Ok, so you use this in your B&D too? Will it overwrite when you deploy this capture again then?

        • Yes, I use this in my build and capture (I assume that B&D was typo). No, it won’t overwrite it as that’s the whole point of supplying the ID parameter as this either creates a unique registry key with that name to store the values under or a unique WMI object with the ID set as the key attribute (or both depending on the switches that you’ve supplied to the script).

  3. Jason,

    I’m curious if you have come across this issue and how you solved it. I ran your script after my task sequence and it merged in the correct information into the registry and WMI per the command line:

    -ID “1803” -WMI -Registry

    I have since decided that I want to add some additional variables to track. So I modified the script and included those additional variables. On the same machine, the variables are imported into the registry but will not import into WMI. When I check the SMSTS.log I see the following error:

    Not found
    At C:\WINDOWS\ccmcache\b\SetOSDInfo.ps1:375 char:9
    + $classInstance[$attrName] = $attrVal
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : OperationStopped: (:) [], ManagementException
    + FullyQualifiedErrorId : System.Management.ManagementException

    I have tried executing outside the TS as follows with the same error:

    [String]$AttributePrefix = “OSDInfo_”
    [String]$ID = “1803”
    $keyValue = “ID”
    New-Variable -Name “$($AttributePrefix)$keyValue” -Value $ID
    New-Variable -Name “$($AttributePrefix)DriverPackage” -Value “NA”

    $customAttributes = Get-Variable -Name “$AttributePrefix*”
    [System.Management.Automation.PSVariable[]]$customAttributes

    $classPath = “root\Kiewit:CompatScan”
    $classObj = [wmiclass]$classPath
    $classInstance = $classObj.CreateInstance()

    foreach ($attr in $customAttributes)
    {
    $attr
    $attr.Name -match “$AttributePrefix(?.*)” | Out-Null
    $attrName = $matches[‘attributeName’]

    if ($attr.Value)
    {
    $attrVal = $attr.Value
    }
    else
    {
    $attrVal = “”
    }

    #$attrName $attrVal

    $classInstance[$attrName] = $attrVal
    #” added attribute value for $($attrName): $($attrVal)” >> $env:temp\newWMIInstance.log

    }
    $classInstance.Put()

    If I only edit variable that were initially created when the script was first ran I have no issues updating them. But if we want to add a new variable the only solution I have found is to delete the Class and let the data populate again.

    Short of doing this any other suggestions?

    • This is correct. the script is designed to create a class and populate it with a new [data] instance or populate an existing class with a new [data] instance. In both cases, the new [data] instance can only contain the attributes defined when the class was created. Adding new attributes to an existing class isn’t part of the script — and I’m not sure off-hand whether you can even do this in WMI anyway.

  4. Not sure if my last post was successful or not. Found an issue, or maybe this is by design, if you run this script against a system for testing and then modify the script to add additional variables that you want to capture in WMI because the class is already created it will not add the new variables to the class.

    When I was reviewing the code the New-WMIClass function checks to see if the Class already exists and if so skips saying the class is already present. This is great but if are testing and looking to add new variables you would have to delete the class from the system to have a new class created. This cumbersome if your are testing with multiple machines to understand what variables you want to capture in WMI.

    • True, but as noted, I don’t think it’s possible to even add attributes to an existing WMI class.

  5. Has this been testing on Windows 10 v1809? I tried adding the script to our OSD task sequence, but it appears to be failing.

    Here is my TS Step:

    Type: Run PowerShell Script
    Name: Set OSD Information
    Package: PRI006E1
    Script name: Set-OSDInfo.ps1
    Parameters: -ID “Deploy” -WMI -Registry
    PowerShell execution policy: Bypass

    And here is what appears in the smsts.log:

    Executing command line: Run Powershell script
    New-Variable : A variable with name ‘OSDInfo_LaunchMode’ already exists.
    At C:\_SMSTaskSequence\Packages\PRI006E1\Set-OSDInfo.ps1:517 char:2
    + New-Variable -Name “$($AttributePrefix)LaunchMode” -Value $tsenv. …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : ResourceExists: (OSDInfo_LaunchMode:String) [New-Variable], SessionStateException
    + FullyQualifiedErrorId : VariableAlreadyExists,Microsoft.PowerShell.Commands.NewVariableCommand

    Path : \\.\root\ITLocal:OSD_Info.ID=”Deploy”
    RelativePath : OSD_Info.ID=”Deploy”
    Server : .
    NamespacePath : root\ITLocal
    ClassName : OSD_Info
    IsClass : False
    IsInstance : True
    IsSingleton : False

    Exception calling “Add” with “3” argument(s): “Invalid parameter ”
    At C:\_SMSTaskSequence\Packages\PRI006E1\Set-OSDInfo.ps1:291 char:13
    + $newClass.Properties.Add($attrName, [System.Management.Ci …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ManagementException

    Not found
    At C:\_SMSTaskSequence\Packages\PRI006E1\Set-OSDInfo.ps1:375 char:9
    + $classInstance[$attrName] = $attrVal
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : OperationStopped: (:) [], ManagementException
    + FullyQualifiedErrorId : System.Management.ManagementException

    Did I do something wrong, or is the current script not compatible with v1809?

    • Yes, fully tested. I’m using it as is at my current customer on Win 10 1809 and I’ve run it at previous customers as well with other versions of Win 10. The above issue has nothing to do with the Windows version though.

      Where exactly in the TS are you running this?

      • Thank you for the reply. I placed it immediately after the Setup Operating System group, so after Setup Windows and Config Manage, then Restart Computer. So at this point the PC has been joined to the domain, but has no started installed any 3rd party apps.

        Don’t laugh at me, but I wasn’t really sure where it should go.

        • Did you get it to work? I am having the same issue, and have it placed in the same spot.

          • We were able to get it to work. First thing is to verify you have enabled PowerShell in your boot image. (Boot image Properties > Optional Components > check Windows PowerShell

            Once this was enabled, I placed the script after the ‘Setup Operating System’ group, which in my environment contains the steps: 1. Setup Windows and Configuration Manager, 2. Restart Computer

            So it is the first action to take place after the computer joins the domain, just prior to installing our custom apps.

            I just verified that it worked successfully. Hope this is helpful.

          • If you are running the script after the Setup Windows and ConfigMgr task, then the boot image is irrelevant as everything after this task runs in the deployed OS.

          • As much sense as that makes, the script failed no matter where I placed it until we turned on Powershell in the boot image.

  6. Since adding it right after Setup Windows step. Does it still put the correct overall time for the TS to run?

  7. How do I get it to write in the root\cimv2 class? right now it writes to root for the new class.

  8. How much info is supposed to be put into WMI?
    All I see in WMI is ID. Install Date, and UEFI. Does it not put the same information from the registry keys?

  9. PowerShell to verify WMI information was set:

    Get-WmiObject -Namespace “root\ITLocal” -Class “OSD_Info”