Add-Member ?

Hi,

I have this code which writes a variable to the task sequence during deployment.

$TSEnv = New-Object -ComObject Microsoft.SMS.TSEnvironment

$models = "IsDesktop", "IsLaptop", "IsVM" | foreach{
New-Object -TypeName PSObject -Property @{"TSVariable"=($_ -replace "Is", "");"Value"=$([System.Convert]::ToBoolean($TSEnv.value($_)))}
}

$TSEnv.value("TSModel") = $models | Where{$_.Value -eq $true} | select -ExpandProperty TSVariable

Works great. But i want to add a variable for Tablet. I have a line of WMI code that will confirm if a tablet

 Get-WmiObject Win32_ComputerSystem | where { $.PlatformType -eq 2 -and $.PlatformType -eq 8 } 

I want to add it to my TSVariable table, but struggling. How can i add a member to the PSObject without removing what is there ? Or is there a better way ?

Thank you !

You’d use Add-Member and add a NoteProperty.

This is more of a question for an SCCM thread on Operating System Deployment. If memory serves, the MDT toolkit contains all of the scripts that are doing the same thing, running a WMI query and creating TS Variables for IsDesktop, IsLaptop and IsVM. The last time I worked with MDT, all of the scripts were VBScript.

  1. You could find the script that is setting this information in the task sequence and add your code. Problem is when you deploy a new MDT toolkit version, you have to re-add the code to the script. Replacing is risky if they've made improvements in the script, you would replace with old code and could break things with cryptic smsts.log errors
  2. You could create a script like above and place it in the MDT Toolkit package and call it after your OS is installed to set it just like you are talking about. I would recommend a naming convention using your company initials so when you are doing a MDT Toolkit update, you can find your scripts quickly (e.g. ztiTCAddIsTablet.vbs for Tech Corporation).

If you were looking for a code sample, try this:

$TSEnv = New-Object -ComObject Microsoft.SMS.TSEnvironment

$IsTablet = Get-WmiObject Win32_ComputerSystem | where { $_.PlatformType -eq 2 -and $_.PlatformType -eq 8 }

if ($IsTablet) {
    $TSEnv.value("IsTablet") = $true
}
else {
    $TSEnv.value("IsTablet") = $false
}

I would modify it to not do the TS variable stuff and test it on a tablet to ensure you are getting TRUE on there and FALSE on Desktops, VMs and Laptops.

Don,

What would be the syntax to add a noteproperty to an existing list ? Everytime i try and add a new member it clears out what is already there.

$Models | Add-Member -type NoteProperty -name “TSVariable” -value “Tablet”

So, if $Models contains more than one object (making it a “collection,” not a “list”), you can’t do that. You have to add members to individual objects, one at a time. If $Models has multiple objects, that means a ForEach loop to enumerate them.

But let’s break down and make sure I’m understanding your code.

$models = "IsDesktop", "IsLaptop", "IsVM" | foreach{
New-Object -TypeName PSObject -Property @{"TSVariable"=($_ -replace "Is", "");"Value"=$([System.Convert]::ToBoolean($TSEnv.value($_)))}
}

It’d probably be easier to just add the property inside that ForEach loop, no? Run your WMI query, figure out if it’s a tablet or not, and then build your object with whatever value you want?

Actually, maybe I don’t understand ;).

So, you’re outputting three objects right now. Every object has a property named TSVariable, with a value of either Desktop, Laptop, or VM. Correct?

So you don’t want to “add” Tablet to an existing object - you just want a NEW OBJECT.

$models = "IsDesktop", "IsLaptop", "IsVM" | foreach{
New-Object -TypeName PSObject -Property @{"TSVariable"=($_ -replace "Is", "");"Value"=$([System.Convert]::ToBoolean($TSEnv.value($_)))}
}
$models += New-Object -Type PSObject -Property @{"TSVariable"="Tablet";"Value"=$whatever}

Right? Sorry - this was a terminology thing; you were using “list” and “table” and I think I got confused about what the goal output was.

Hi Don,
Thank you. Yes, i want to add a new “object” to the existing objects…if that makes sense ! But the new object is evaluated in a different way to the other 3, in this case.

You want to add a new object to the existing collection of objects. So you can use the code I just posted to do that. You can see where I assigned the value $whatever; you’d just put your $True or $False in there before creating the new, fourth object.

Many thanks Don, i’ll have a look into that.

Don, sorry, am i on the right lines ?

$TSEnv = New-Object -ComObject Microsoft.SMS.TSEnvironmen

$IsTablet = Get-WmiObject Win32_ComputerSystem | where { $_.PlatformType -eq 2 -and $_.PlatformType -eq 8 }
$models = "IsDesktop", "IsLaptop", "IsVM" | foreach{
New-Object -TypeName PSObject -Property @{"TSVariable"=($_ -replace "Is", "");"Value"=$([System.Convert]::ToBoolean($TSEnv.value($_)))}
}
$models += New-Object -Type PSObject -Property @{"TSVariable"="Tablet";"Value"=[boolean]$IsTablet}

$TSEnv.value("TSModel") = $models | Where{$_.Value -eq $true} | select -ExpandProperty TSVariable

Looks like it.

Your WMI query isn’t going to return True or False, it’s going to return a record or NULL. So you need to do something more like this:

If ( Get-WmiObject Win32_ComputerSystem | where { $_.PlatformType -eq 2 -and $_.PlatformType -eq 8 } ) {
    $IsTablet = $true
}
else {
    $IsTablet = $false
}

$IsTablet

Rob, that’s why I put [boolean] in front of the variable that contains the wmi query result.
Seems to work.