Collect OSD / IPU Info with Hardware Inventory

Update 2019.01.22 To include User Account that triggered the Upgrade & Unique Build Record Info. Blog Post for "Gather Account Name during IPU" HERE

Update 2018.08.01 To include Hard  Blocker from  Compat Scan, requires you to add a step into the TS to capture the Hard  Blocker to a  TS Variable,  Blog Post HERE

Update 2018.06.05 - I've posted the first WaaS Post, which incorporates this Script into a Compatibility Scan Task Sequence.  I've updated the script since this post, which is available to download, along with the Task Sequence Export in this POST HERE

Several years ago I started to use Jason Sandys’ OSDInfo Script.  I liked the idea of having a script run during OSD that would write information to WMI, which made it easy to inventory.  Now I do IPU (In Place Upgrade) so much more than OSD, and I wanted to do the same, gather important information from IPU and be able to use it for Reporting or creating collection queries.

I’ve taken Jason’s script and modified it… a lot.  All of his plumbing is still in place (functionality to add information to WMI & Registry), but I’ve added a lot of logic around using the script for different functions.

The script is now broken into 3 sections, OSD (Operating System Deployment), CS (Compatibility Scan), IPU (In Place Upgrade).  Using TS Variables, the script will run different sections of the script.  This allows me to use the same script in numerous scenarios.
First, I’ll show you results, and then go into details about how it’s done.  But I feel it’s easier to understand the script and process if you can see the end product.Registry, Creates WaaS Key, then subkeys for OSD and IPU Build Numbers to keep thing separated for historical data.  If you’re a Reg2Mof person, this is probably the way you’ll want to go.

OSD Info:
image

CS & IPU:
CompatScan = Green
IPU = Yellow
Both Processes = Blue (IPU overwrites CS info)

image

WMI: (Makes it easy to import into Hardware Inventory, but the data is spread out a bit instead of in one nice view)
Classes: CompatScan / IPU / OSD
Instances: Build Number
Prosperities: Details from each process

image

SQL: (When using WMI & Hardware Inventory)

OSD:
image
CompatScan:
image
IPU:
image

Used for Report:
image

Ok, now to the “How” section, the Script:  Can be downloaded along with the entire WaaS_Scripts Package Here: WaaS_Scripts Package (305 downloads)
Requires Several TS Variables to function, will cover after script.

Step in Task Sequences
Required Variables in TS:
SetOSDInfoType: Set to OSD / CS / IPU - Tells the Script which section to run.

I set the osdbuildversion variable in the beginning of the TS, which gets used in the script & command line. NOTE… I’ve changed this to SMSTS_BUILD, as I was using that in other places and make my life eaiser for consisteancy.

image

SMSTS_StartTSTime - Records time at the very start of the TS

SMSTS_FinishTSTime - Records time near the end of the TS, used in the script to calculate run time of TS

CheckReadinessResult: If Check Readiness Fails, Set to FAIL

SMSTS_StartUpgradeTime - Records time right before Upgrade Step Starts.

SMSTS_FinishUpgradeTime - Records time right after Upgrade Step finishes, to calculate upgrade time

SMSTS_DMDepartment - Collection Variable - Specific to my Test Lab to help track which Department a computer belongs to
SMSTS_DMLocation - Collection Variable - Specific to my Test Lab to help track which Branch computer belongs to
- These are just for sample to show you can collect information like this during IPU / OSD.  Recommend Customization them for your environment or removing them from the script.

OSD: Run Powershell Script:

image

CompatScan: Run PowerShell Script

image

IPU: Run PowerShell Script:

image

Add to Hardware Inventory: Set Classes –> Add –> Connect –> Computer Name of machine you ran the script on and you confirmed the WMI NameSpace and values are created –> Ensure you change the namespace to the namespace you specified in the TS-> Connect
image

Check the Boxes and click OK: (I’ve already done this, which is why they say “exists” in this screen capture, and the class names are greyed out, but when you do it the first time, you’ll be able to check those boxes)
image

You can then verify all the fields then and check the ones you want. If you change the script in the future, you’ll need to come back in here and modify what you’ve checked.
OSD:
image
CompatScan:
image

IPU:
image

Used in Collection Queries:

 

And now, as machines run through your process, and hardware inventory is collected, you’ll have useful data to provide.

If you have any questions, let me know.  I've been running this so long, that I might have missed a step I needed to set it all up originally.

Published originally on garytown.com

16 thoughts on “Collect OSD / IPU Info with Hardware Inventory”

  1. Gary, this looks very interesting and i am trying to test it in my IPU TS. I do have few questions...but to start where do you run the script in your TS?

  2. Thanks again...This is great and everything is working...For some reason I have TSRun time as 0. I have SMSTS_StartUpgradeTime and SMSTS_FinishUpgradeTime before and after Upgrade Operating System step. I wanted to ask if you can have a post about a report you are using in this post or maybe share an rdl file?
    Thank you.

  3. I'm having an issue with the TS Run time and It looks like it because i'm in Australia and our date time format is different to US.
    SMSTS_StartTSTime = 10/26/2018 10:47:27 AM
    SMSTS_FinishTSTime = 26/10/2018 11:11:45 AM
    Here you can see that the StartTSTime is in the US date format where at the end of the task sequence it's in the Australia date time format. Any ideas on how we could work around this issue?

    • Interesting, so at the beginning of the TS. I assume this is OSD, not IPU, the machine is running in US, then later in the process you've applied the Australian region. I'd play with formatting it. Check out: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/get-date?view=powershell-6 -Format FileDateTime. Just remember, if you change for format, you'll have to update each step that sets a time stamp, and update the script as well. Hope that helps. Hit me up on twitter if you run into any issues. Once you've made all the changes, I'd like to hear your results.

      • Correct it's only an issue on OSD as the WinPE we are using is en-US.
        I managed to find a way around it by using the following command instead of Get-Date for the SMSTS_StartTSTime variable.
        [datetime]::Now.ToString([cultureinfo]'en-AU')

        Also I did have issues with calculating the TSRunTime in minutes as well.
        I changed the first Difference line to the below.
        $Difference = ([datetime]::ParseExact($TSEnv.Value('SMSTS_FinishTSTime'),"dd/MM/yyyy h:mm:ss tt",$null)) - ([datetime]::ParseExact($TSEnv.Value('SMSTS_StartTSTime'),"dd/MM/yyyy h:mm:ss tt",$null))

        • Had issues still calculating the TSRunTime and I've found that this works.
          $Difference = [datetime]$TSEnv.Value('SMSTS_FinishTSTime') - [datetime]$TSEnv.Value('SMSTS_StartTSTime')
          Not sure if your line works or not as I haven't had a chance to try it again but I have just less round brackets.

          Thanks for this amazing script.

  4. Hey Gary... I've implemented what you have here and the registry is getting populated properly but when I look at the WMI on the IPU class on the instance IPU.ID it's only pulling in the ID and WaaS_Stage and not the rest of the IPU_* registry items. I'm running my compat scan and IPU in one TS so things go like this in the TS:

    SetOSDInfoType = CS
    Do the compat scan steps
    Pass or fail run Set-ComboInfo.ps1 with the following params: -ID "%SMSTS_Build%" -WMI -Registry -Class "CompatScan" -Namespace ""
    SetOSDInfoType = IPU
    Do the OS Upgrade steps
    Pass or fail run Set-ComboInfo.ps1 with the following params: -ID "%SMSTS_Build%" -WMI -Registry -Class "IPU" -Namespace ""

    Any ideas???

    • Figured it out and am posting as reply to my own comment in case anyone else has a setup similar to mine:

      The problem was if it failed during the compat scan steps what I had as the "Pass or fail" on the compat scan... if it failed I was actually running Set-ComboInfo.ps1 with the following params: -ID "%SMSTS_Build%" -WMI -Registry -Class "IPU" -Namespace "" instead of -Class "CompatScan" so when I fixed whatever the issue was and ran the IPU again it wasn't writing anything to WMI for the IPU classes. In my fail section of my TS I've added a condition on what SetOSDInfoType is and to run the correct arguments on Set-ComboInfo.ps1.

  5. I am having issues with Jason's part adding the info to WMI, it creates the Class, and only adds ID, Install Date, and UEFI.

    When I pause the TS, and run it manually, the PS dump a bunch of errors saying not found.
    Any suggestions, am I missing something?

    PS C:\Temp1> .\Set-OSDInfo.ps1 -ID Deploy3 -WMI
    Not found
    At C:\Temp1\Set-OSDInfo.ps1:375 char:9
    + $classInstance[$attrName] = $attrVal
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : OperationStopped: (:) [], ManagementException
    + FullyQualifiedErrorId : System.Management.ManagementException

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

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

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

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

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

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

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

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

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

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

    Path : \\.\root\cimv2:OSD_Info.ID="Deploy3"
    RelativePath : OSD_Info.ID="Deploy3"
    Server : .
    NamespacePath : root\cimv2
    ClassName : OSD_Info
    IsClass : False
    IsInstance : True
    IsSingleton : False

    • What's the context of when you're running the script? OSD / IPU? WinPE / Full OS? You're launching the command prompt via the Task Sequence and confirming you have access to the Task Sequence Engine? Does it write to the registry ok if you try that? Have you tried changing the Class & NameSpace params? I would be curious if you were to download my old TS that I used to run that in, and copy the step and see if you have different results.
      I know that I had some issues with writing to WMI when I first started out, and ended up having to tweak the Names I was using to get it to work. I no longer write to WMI, and only registry and use Reg2Mof, it's been working better.

  6. Hello,

    This is likely a super dumb question. I download your TS's to start playing with and trying to incorporate some of the advanced techniques your using. We are NOT at 1903 sccm yet though, so I believe I HAVE to use the older TS examples? Can/Should I be trying to use the latter ones that indicate they require 1903? IS that a good idea? I currently tried the older pre-cache one but noticed it did not Align with what I added to my inventory.

    So my next question is - is there much reason to try and use the Newer REGtoMOF stuff you have with all those keys or should i be trying to get the ones mentioned above into my inventory? Are those reg keys and mof files here somewhere to download?

Leave a Comment

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