Hi, I has written PowerShell function which creates registry entry on remote computer(s). Path where entry is created depends on whether remote computer runs 32-bit or 64-bit Windows. In BEGIN block of advanced function I have following lines:
$property = @{
Path = "" #empty string, it will take value depending on OS architecture of remote pc
Name = "WindowsLogonLocal"
PropertyType = "String"
Value = "LCL-AAA-FORCE-4651"
}
In PROCESS block I have following lines (in foreach loop):
$param = @{
ComputerName = $Computer
Class = 'Win32_OperatingSystem'
}
if((Get-WmiObject @param).OSArchitecture -eq '32-bit') {
$property.Set_Item("Path","HKLM:\software\pexim\config")
}
if((Get-WmiObject @param).OSArchitecture -eq '64-bit') {
$property.Set_Item("Path","HKLM:\software\wow6432node\pexim\config")
}
Invoke-Command -ComputerName $Computer -ScriptBlock {
New-ItemProperty @using:property
}
I want to optimize this. Remote computers run PowerShell v2 but I would like to avoid using Get-WmiObject since WMI is almost thing of the past. I could use Invoke-Command -ComputerName $Computer -ScriptBlock {[System.Environment]::Is64BitOperatingSystem} to test if remote computer runs 32-bit or 64-bit Windows but then I would have two Invoke-Command lines.
Not true. If you use the -ScriptBlock (or its alias -Command) parameter, you can run a multiple commands within the block. Or you can use the -FilePath parameter to specify a local script to be run on the remote system.
I did not mean two lines inside script block but two lines with Invoke-Command cmdlet:
$isOS32bit = Invoke-Command -ComputerName $Computer -ScriptBlock {-not[System.Environment]::Is64BitOperatingSystem
}
if($isOS32bit) {$property.Set_Item(“Path”,“HKLM:\software\pexim\config”)}
else {$property.Set_Item(“Path”,“HKLM:\software\wow6432node\pexim\config”)}
Invoke-Command -ComputerName $Computer -ScriptBlock {
New-ItemProperty @using:property
}
First of all, don’t expect WMI (or CIM) to become “a thing of the past” anytime soon. A lot of PowerShell stuff relies heavily on these technologies, and it is perfectly fine to utilize it in your code (all a matter of taste).
I think you misunderstood Bob’s comment. What he is saying is that what you try to achieve, you can do with a single call to Invoke-Command by using a ScriptBlock with several lines of code.
You might do something like this (untested):
Invoke-Command -ComputerName $Computer -ScriptBlock {
$property = $using:property
# If x64 (64bit) system
if ($env:PROCESSOR_ARCHITECTURE -eq 'AMD64')
{
$property.Set_Item('Path','HKLM:\software\wow6432node\pexim\config')
}
# If x86 (32bit) system
else
{
$property.Set_Item('Path','HKLM:\software\pexim\config')
}
New-ItemProperty @property
}
Ok, so it is perfectly normal to assign value of local variable to variable in remote session and continue using it ($property = $using:property) or modify it. Speaking of WMI (not CIM), I am limited to use WMI (DCOM) or CIM (over DCOM) since my remote clients are running Windows 7 which comes with PowerShell v2. WSMAN can not be used and DCOM (RPC) is not ideal communication protocol.