Passing a variable inside s nested loop - powershell

I'm tying to work out how I pass a variable from an if statement into a nested if statement starting at:
If ($server -eq $env:COMPUTERNAME)
Foreach ($comp in $computer) {
$server = split-FQDN $comp -part H
$domain = Split-FQDN $comp -part D
#Set the domain based parameters
If ($domain -eq '1.fqdn.com') {
set-domparams $domain $userprompt $userpass
}
Elseif ($domain -eq '2.fqdn.com') {
set-domparams $domain $userprompt $userpass
}
Elseif ($domain -eq '3.fqdn.com') {
set-domparams $domain $userprompt $userpass
}
ElseIf ($domain -eq '4.fqdn.com') {
set-domparams $domain $userprompt $userpass
}
ElseIf ($domain -eq '5.fqdn.com') {
set-domparams $domain $userprompt $userpass
}
ElseIf ($domain -eq '6.fqdn.com') {
set-domparams $domain $userprompt $userpass
}
If ($server -eq $env:COMPUTERNAME) {
$server = $_
#clear Kerberos ticket cache
Invoke-Expression -Command:'cmd.exe /c klist purge' | Out-Null
$buildlogsuccess = check-buildlog $domain
$chocologstatus = Invoke-Command -ScriptBlock {check-choco}
$KMSvalues = Invoke-Command -ScriptBlock {get-winlicense}
$parentOU = get-ParentOU (Get-ADComputer -Server $dc -SearchBase $searchbase -Filter {name -eq $server} -Credential $fetchCreds) | select -expand parentou
$SCCMcheck = Invoke-Command -ScriptBlock {get-sccmstatus}
$scomcheck = Invoke-Command -ScriptBlock {get-scomstatus} -argumentlist $scom
$AV = Invoke-Command -ScriptBlock {get-avstatus}
$wfirewall = Invoke-Command -ScriptBlock {(get-service MpsSvc).status}
$net35 = Invoke-Command -ScriptBlock {(Get-WindowsFeature NET-Framework-Core).installed}
$admins = Invoke-Command -ScriptBlock {check-admins}
$DomainComms = Invoke-Command -ScriptBlock {get-domaininfo}
$bigfix = Invoke-Command -ScriptBlock {get-bigfix}
}
Else {
$server = $_
#clear Kerberos ticket cache
Invoke-Expression -Command:'cmd.exe /c klist purge' | Out-Null
#start running functions against target server(s) to get required info
$PSSession = New-PSSession -ComputerName $comp -Credential $fetchCreds -Name $server
$buildlogsuccess = check-buildlog $domain
$chocologstatus = Invoke-Command -Session $pssession -ScriptBlock ${function:check-choco}
$KMSvalues = Invoke-Command -Session $PSSession -ScriptBlock ${Function:get-winlicense}
$parentOU = get-ParentOU (Get-ADComputer -Server $dc -SearchBase $searchbase -Filter {name -eq $server} -Credential $fetchCreds) | select -expand parentou
$SCCMcheck = Invoke-Command -Session $PSSession -ScriptBlock ${Function:get-sccmstatus}
$scomcheck = Invoke-Command -Session $PSSession -ScriptBlock ${function:get-scomstatus} -argumentlist $scom
$AV = Invoke-Command -Session $PSSession -ScriptBlock ${Function:get-avstatus}
$wfirewall = Invoke-Command -Session $PSSession -ScriptBlock {(get-service MpsSvc).status}
$net35 = Invoke-Command -Session $PSSession -ScriptBlock {(Get-WindowsFeature NET-Framework-Core).installed}
$admins = Invoke-Command -Session $PSSession -ScriptBlock ${Function:check-admins}
$DomainComms = Invoke-Command -Session $PSSession -ScriptBlock ${Function:get-domaininfo}
$bigfix = Invoke-Command -Session $PSSession -ScriptBlock ${Function:get-bigfix}
#clean up the remote session
Remove-PSSession -Name $server
}
I already have some global variables in use that are passed by a loaded function, but I'm trying to avoid do the same for this bit of code and understand how to pass my remaining variables ($comp, $computer and $domain) correctly to the next inner loop.
I've tried getting $server to work doing the following but haven't had any success as of yet:
$server = $_

This is more code review opinion instead of an answer, but anyway.
Instead of long if...elseif constructs, why not use table driven programming? If there are lots of domains and they require different credentials, maintaining the if...elseif is tedious. Store the credentials in custom Powershell objects and those in a hashtable. Then lookup can be done with the domain name only. Like so,
# Declare a hashtable and add custom credential objects
$creds=#{}
$creds.Add('foo.fqdn', $(New-Object –TypeName PSObject –Prop #{'Domain'='foo.fqdn'; 'User'='foo.user'; 'Pass'='foo.pass'}))
$creds.Add('bar.fqdn', $(New-Object –TypeName PSObject –Prop #{'Domain'='bar.fqdn'; 'User'='bar.user'; 'Pass'='bar.pass'}))
$creds.Add('zof.fqdn', $(New-Object –TypeName PSObject –Prop #{'Domain'='zof.fqdn'; 'User'='zof.user'; 'Pass'='zof.pass'}))
# Later when credentials are needed, check if the domain is present
# and get the values from the hashtable.
if($creds.ContainsKey($domain) {
set-domparams $domain $creds[$domain].User $creds[$domain].Pass
} else {
write-warning "Domain $domain not found!"
}

I think this is a non-question as your variables are valid within the loops/statements they are created.
Foreach ($comp in $computer) {
$server = split-FQDN $comp -part H
$domain = Split-FQDN $comp -part D
if($true){
# $comp, $server and $domain are all in scope
Write-host "$comp $server $domain"
if($true){
# also true in nested if statements
Write-host "$comp $server $domain"
}
}
Else{
# $comp, $server and $domain are all in scope
Write-host "$comp $server $domain"
}
}
# outside, $comp is not available, only $computer
# $server and $domain will only contain the values from the last run of the foreach loop.

Related

How to loop through Multiple Machines in a PSSession such that I execute Invoke-Command against the correct Machine?

My Powershell Script below wants to retrieve multiple registry values, from a set of Windows Services (200+), from multiple machines (up to 8 machines). Since I'm retrieving quite a lot of info, I decided to use New-PSSession.
But whenever it gets into the scriptblock of the foreach loop, it executes it on the incorrect machine and thus eventually errors out saying
The Error:
Cannot find path 'HKLM:\system\currentcontrolset\services\SomeServiceName' because it does not exist.
+ CategoryInfo : ObjectNotFound: (HKLM:\system\cu...ces\SomeServiceName:String) [Get-ItemProperty], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetItemPropertyCommand
+ PSComputerName : WEB002
The Powershell Script:
$MyCustomServiceArray = #()
$c1 = 0
$s = New-PSSession -ComputerName WEB001, WEB002
$MyCustomServices = Invoke-Command -session $s -scriptblock {Get-WmiObject -Class win32_service |
Where-Object -FilterScript {$_.Displayname -like "*Special Service for Me*"} |
Select PSComputerName, Name, DisplayName, State, StartMode, StartName, PathName |
Sort DisplayName}
foreach($MyCustomService in $MyCustomServices)
{
$MyCustomServiceName = $MyCustomService.Name
$RegistryPathForService = "hklm:\system\currentcontrolset\services\$MyCustomServiceName"
$c1 += 1
Write-Host "$c1. $MyCustomServiceName`n"
$StartUpParameter = Invoke-Command -session $s -scriptblock {(Get-ItemProperty $using:RegistryPathForService).startupparameter}
if ($StartUpParameter -eq $null) {$StartUpParameter = ""}
$DatabaseServerName = Invoke-Command -session $s -scriptblock {(Get-ItemProperty $using:RegistryPathForService).servername}
if ($DatabaseServerName -eq $null) {$DatabaseServerName = ""}
$DatabaseName = Invoke-Command -session $s -scriptblock {(Get-ItemProperty $using:RegistryPathForService).database}
if ($DatabaseName -eq $null) {$DatabaseName = ""}
$NetType = Invoke-Command -session $s -scriptblock {(Get-ItemProperty $using:RegistryPathForService).nettype}
if ($NetType -eq $null) {$NetType = ""}
$ObjectCacheSize = Invoke-Command -session $s -scriptblock {(Get-ItemProperty $using:RegistryPathForService).objectcache}
if ($ObjectCacheSize -eq $null) {$ObjectCacheSize = 0}
$Row = "" | Select HostName,ServiceName,StartUpParameter,ServiceDisplayName,Status,StartUpType, `
DatabaseServerName,DatabaseName,NetType,ObjectCacheSize, `
LogOnName,PathName
$Row.HostName = $MyCustomService.PSComputerName
$Row.ServiceName = $MyCustomService.Name
$Row.StartUpParameter = $StartUpParameter
$Row.ServiceDisplayName = $MyCustomService.DisplayName
$Row.Status = $MyCustomService.State
$Row.StartUpType = $MyCustomService.StartMode
$Row.DatabaseServerName = $DatabaseServerName
$Row.DatabaseName = $DatabaseName
$Row.NetType = $NetType
$Row.ObjectCacheSize = $ObjectCacheSize
$Row.LogOnName = $MyCustomService.StartName
$Row.PathName = $MyCustomService.PathName
$MyCustomServiceArray += $Row
}
$MyCustomServiceArray | Export-Csv -NoTypeInformation -Path "C:\Users\GaryTheBrave\Documents\AllMyCustomServices.csv"
Is there a way to loop through these Multiple Machines in the correct order?
The Solution was, as Lee_Daily hinted, Looping through sessions. Thanks Lee_Daily!!!
Here is the modified Powershell Script that works perfectly
$MyCustomServiceArray = #()
$c1 = 0
$sessions = New-PSSession -ComputerName WEB001, WEB002
foreach($session in $sessions)
{
$MyCustomServices = Invoke-Command -session $session -scriptblock {Get-WmiObject -Class win32_service |
Where-Object -FilterScript {$_.Displayname -like "*Special Service for Me*"} |
Select PSComputerName, Name, DisplayName, State, StartMode, StartName, PathName |
Sort DisplayName}
foreach($MyCustomService in $MyCustomServices)
{
$MyCustomServiceName = $MyCustomService.Name
$RegistryPathForService = "hklm:\system\currentcontrolset\services\$MyCustomServiceName"
$c1 += 1
Write-Host "$c1. $MyCustomServiceName`n"
$StartUpParameter = Invoke-Command -session $session -scriptblock {(Get-ItemProperty $using:RegistryPathForService).startupparameter}
if ($StartUpParameter -eq $null) {$StartUpParameter = ""}
$DatabaseServerName = Invoke-Command -session $session -scriptblock {(Get-ItemProperty $using:RegistryPathForService).servername}
if ($DatabaseServerName -eq $null) {$DatabaseServerName = ""}
$DatabaseName = Invoke-Command -session $session -scriptblock {(Get-ItemProperty $using:RegistryPathForService).database}
if ($DatabaseName -eq $null) {$DatabaseName = ""}
$NetType = Invoke-Command -session $session -scriptblock {(Get-ItemProperty $using:RegistryPathForService).nettype}
if ($NetType -eq $null) {$NetType = ""}
$ObjectCacheSize = Invoke-Command -session $session -scriptblock {(Get-ItemProperty $using:RegistryPathForService).objectcache}
if ($ObjectCacheSize -eq $null) {$ObjectCacheSize = 0}
$Row = "" | Select HostName,ServiceName,StartUpParameter,ServiceDisplayName,Status,StartUpType, `
DatabaseServerName,DatabaseName,NetType,ObjectCacheSize, `
LogOnName,PathName
$Row.HostName = $MyCustomService.PSComputerName
$Row.ServiceName = $MyCustomService.Name
$Row.StartUpParameter = $StartUpParameter
$Row.ServiceDisplayName = $MyCustomService.DisplayName
$Row.Status = $MyCustomService.State
$Row.StartUpType = $MyCustomService.StartMode
$Row.DatabaseServerName = $DatabaseServerName
$Row.DatabaseName = $DatabaseName
$Row.NetType = $NetType
$Row.ObjectCacheSize = $ObjectCacheSize
$Row.LogOnName = $MyCustomService.StartName
$Row.PathName = $MyCustomService.PathName
$MyCustomServiceArray += $Row
}
}
$MyCustomServiceArray | Export-Csv -NoTypeInformation -Path "C:\Users\GaryTheBrave\Documents\AllMyCustomServices.csv"

Can't assign value to a variable inside of Invoke-Command

It seems to be strange but I can't assign a value to variable inside of Invoke-Command. Here is the code below but when print out $targetComputerPath it's simply empty. What's wrong?
foreach ($item in $computersPath){
$computername = $item.Name
$username = $item.UserID
Write-Host computer $computername and user $username
if (Test-Connection -ComputerName $computername -Count 1 -ErrorAction SilentlyContinue)
{
if ($((Get-Service WinRM -ComputerName $computername).Status) -eq "stopped")
{
(Get-Service WinRM -ComputerName $computername).Start()
}
Invoke-Command -ComputerName $computername -ScriptBlock {
if ($((Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion").ReleaseId) -eq "1903" )
{
$targetComputerPath = "\\"+$computername+"\c$\Users\"+$username+"\Desktop\"
write-host "1903"
}
else
{
$targetComputerPath = "\\"+$computername+"\c$\Users\"+$username+"\Desktop\"
write-host "something else"
}
}
}
write-host $targetComputerPath
}
The point of WinRM is that you take a script block, and execute it on a different machine.
None of the variables you define in the host script will be available on the remote machine.
This becomes more apparent when you separate the "task", a.k.a the script block, from the Invoke-Command, like this:
$task = {
$version = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion"
if ($version.ReleaseId -eq "1903") {
# note that `$username` cannot be available here, it's never been defined!
return "\\$env:COMPUTERNAME\c$\Users\$username\Desktop"
} else {
return "\\$env:COMPUTERNAME\c$\Users\$username\Desktop"
}
}
foreach ($item in $computersPath) {
$computername = $item.Name
$username = $item.UserID
Write-Host computer $computername and user $username
if (Test-Connection -ComputerName $computername -Count 1 -ErrorAction SilentlyContinue) {
$winrm = Get-Service WinRM -ComputerName $computername
if ($winrm.Status -eq "stopped") { $winrm.Start() }
$targetComputerPath = Invoke-Command -ComputerName $computername -ScriptBlock $task
Write-Host "The machine returned: $targetComputerPath"
}
}
As you can see, you can return values from the script block and they will be available as the return value of Invoke-Command.
If you want to pass arguments to your script block, this thread talks about that: How do I pass named parameters with Invoke-Command?

Trying to verify remote command passed was successful in PowerShell

I am still researching the best way to do this. If anyone has a suggestion please let me know.
I am looking to pass PowerShell commands to a remote machine and receive verification that the command was successful.
The script should not proceed until result is received.
If command fails it should attempt again until it is successful on the remote computer, failure may occur if AD and Skype replication has not completed.
Here is what I have so far.
Not quite working but the above 3 rules. If there is a better way of doing this I am all ears.
$SkypeFeRemoteComputers = Get-SkypeRegistrarPoolInfo -Pool $RegistrarPool
$RemoteFEComputerCompletedSuccessfull = $false
foreach ($Computer in $SkypeFeRemoteComputers) {
if ($RemoteFEComputerCompletedSuccessfull -eq $false) {
try {
Invoke-Command -ComputerName $Computer -AsJob -JobName myJob_NewCommonAreaPhone -ErrorAction Stop -ArgumentList $LineURI,$RegistrarPool, $OU_CommonArea, $Description, $DisplayName, $DisplayNumber, $SIP -ScriptBlock {
Param($R_LineURI, $R_RegistrarPool, $R_OU_CommonArea, $R_Description, $R_DisplayName, $R_DisplayNumber, $R_SIP)
New-CsCommonAreaPhone -LineUri $R_LineURI -RegistrarPool $R_RegistrarPool -OU $R_OU_CommonArea -Description $R_Description -DisplayName $R_DisplayName -DisplayNumber $R_DisplayNumber -SipAddress $R_SIP -WhatIf;
Move-CsCommonAreaPhone -Identity $R_SIP -Target $R_RegistrarPool;
Grant-CsClientPolicy -PolicyName "SkypeUI" -Identity $R_SIP;
Grant-CsVoicePolicy -PolicyName "NA-TX-LAP" -Identity $R_SIP;
Grant-CsDialPlan -PolicyName "NA-TX-LAP" -Identity $R_SIP;
Set-CsClientPin -Identity $R_SIP -Pin 1111;
}
Get-Job
$Result = Invoke-Command -Session $Session -ScriptBlock {
Receive-Job -Name myJob_NewCommonAreaPhone -Keep
}
if ($Result -eq $true) {
$RemoteFEComputerCompletedSuccessfull = $true
}
} catch {
Add-Content Unavailable-Computers.txt $Computer
}
}
}
Write-Host "New-CsCommonAreaPhone -LineUri $lineuri -RegistrarPool $SFBFQDNRegistrarPool -OU $OU -Description $Description -DisplayName $DisplayName -DisplayNumber $DisplayNumber -SipAddress $SIP"
} else {
Write-Host "Set-CsCommonAreaPhone -identity $sip -sipaddress $sip -DisplayName $phone.Display -DisplayNumber $phone.Display"
}
}
Somethings I am researching to do this is perhaps also Invoke-Expression.
I have not yet found a solution to validate the script sent ran successfully or not. However the next best item I could come up with was to test that WinRM I could communicate and would accept commands. Then I guess I have to just trust WinRM completed the Invoke Command.
Function Enable-CommonAreaPhones
{
[CmdletBinding()]
param
(
#[Parameter(Position = 2)]
[Parameter(Mandatory)]
$DisplayName,
[Parameter(Mandatory)]
$SIP,
[Parameter(Mandatory)]
$LineURI,
[Parameter(Mandatory)]
$OU_CommonArea,
[Parameter(Mandatory)]
$CreateNewCAP = $true,
[Parameter(Mandatory)]
$RegistrarPool,
[Parameter(Mandatory)]
$DisplayNumber,
[Parameter(Mandatory)]
$Description
)
<#
dynamicparam {
#https://mcpmag.com/articles/2016/10/06/implement-dynamic-parameters.aspx
#https://stackoverflow.com/questions/42318419/powershell-using-dynamic-parameters-value
#https://github.com/PowerShell/PowerShell/issues/3704
$ParameterName_SFBRegistrarPool = 'SFBRegistrarPool'
$ParamAttrib = New-Object System.Management.Automation.ParameterAttribute
$ParamAttrib.Mandatory = $true
$ParamAttrib.ParameterSetName = '__AllParameterSets'
$AttribColl = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
$AttribColl.Add($ParamAttrib)
$ValidateItems = (get-csservice -Registrar).PoolFqdn
$AttribColl.Add((New-Object System.Management.Automation.ValidateSetAttribute($ValidateItems)))
$RuntimeParam = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName_SFBRegistrarPool, [string], $AttribColl)
$RuntimeParamDic = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
$RuntimeParamDic.Add($ParameterName_SFBRegistrarPool, $RuntimeParam)
return $RuntimeParamDic
}
begin
{$RegistrarPool = $PsBoundParameters[$ParameterName_SFBRegistrarPool]}
process
{}
End
{}
#>
if ($CreateNewCAP)
{
<#
#$Description = "Huddle-N405-172B"
#$DisplayName = "(713)577-3160"
#$DisplayNumber = "+1-713-577-3160"
#$LineURI = 'tel:+17135773160;ext=3160'
#$SIP = 'sip:Huddle-N405-172B.BR172B#mrcglobal.com'
#$OU = "OU=172B LA PORTE -- TX,OU=Gulf Coast,OU=CAP,OU=Lync,DC=mcjunkinredman,DC=com"
#$RegistrarPool = 'hexlsfepool.mcjunkinredman.com'
#>
param($LineURI,$RegistrarPool, $OU_CommonArea, $Description, $DisplayName, $DisplayNumber,$SIP )
write-host "New-CsCommonAreaPhone -LineUri $lineuri -RegistrarPool $SFBFQDNRegistrarPool -OU $OU -Description $Description -DisplayName $DisplayName -DisplayNumber $DisplayNumber -SipAddress $SIP"
New-CsCommonAreaPhone -LineUri $LineURI -RegistrarPool $RegistrarPool -OU $OU_CommonArea -Description $Description -DisplayName $DisplayName -DisplayNumber $DisplayNumber -SipAddress $SIP -WhatIf;
Grant-CsClientPolicy -PolicyName "SkypeUI" -Identity $SIP;
Grant-CsVoicePolicy -PolicyName "NA-TX-LAP" -Identity $SIP;
Grant-CsDialPlan -PolicyName "NA-TX-LAP" -Identity $SIP;
#Set-CsClientPin –Identity $SIP -Pin 1111;
#Move-CsCommonAreaPhone -Identity $SIP -Target $R_RegistrarPool;
}
Else
{
#Get-CsCommonAreaPhone | Set-CsCommonAreaPhone -Enabled $True
#Get-CsCommonAreaPhone -Filter {Description -eq $Null} | Set-CsCommonAreaPhone -Description "Common area phone"
#Get-CsCommonAreaPhone -Filter {LineUri -eq "tel:+14255556710"} | Set-CsCommonAreaPhone -DisplayName "Employee Lounge"
}
}
function invoke-SkypeObject_RemoteModification_CommonAreaPhones
{
#Finds all Front End Servers
$SkypeFeRemoteComputers = Get-SkypeRegistrarPoolInfo -Pool $RegistrarPool
$RemoteFEComputerCompletedSuccessfull = $false
ForEach ($Computer in $SkypeFeRemoteComputers)
{
#Validates Command has only ran on 1 machine
#Validates the computer exists and can accept invoke commands via the WinRM Command
If ((!($RemoteFEComputerCompletedSuccessfull)) -and (Test-Connection -ComputerName $env:COMPUTERNAME -Quiet) -and (Test-WSMan -ComputerName $computer -ErrorAction Ignore))
{
#https://ss64.com/ps/syntax-functions.html
$scriptblock = $executioncontext.InvokeCommand.NewScriptBlock(${function:Enable-CommonAreaPhones})
Invoke-Command -Session $allsession -ScriptBlock $scriptblock -ArgumentList $R_LineURI,$R_RegistrarPool, $R_OU_CommonArea, $R_Description, $R_DisplayName, $R_DisplayNumber,$R_SIP -ErrorVariable errorMsg
Invoke-Command -Session $allsession -ScriptBlock ${function:Enable-CommonAreaPhones} -ArgumentList $R_LineURI,$R_RegistrarPool, $R_OU_CommonArea, $R_Description, $R_DisplayName, $R_DisplayNumber,$R_SIP -ErrorVariable errorMsg
$RemoteFEComputerCompletedSuccessfull = $true
}
}
}

powershell -parallel not working

I am writing a PowerShell script to display the status of free space and CPU, below is snippet:
function Get_FreeSpace ($authType, $comp) {
$freespace = Invoke-Command -ScriptBlock {
Get-WmiObject Win32_LogicalDisk -Filter "DeviceID='E:'" |
Select-Object Size,Freespace
} -ComputerName $comp -Credential $authType
$freesize = [String]::Format("{0:P2}" -f ($freespace.Freespace / $freespace.Size))
return $freesize
}
function Get_CPUAverage ($authType, $comp) {
$Cpu_Average = Invoke-Command -ScriptBlock {
Get-WmiObject Win32_Processor |
Measure-Object -Property LoadPercentage -Average |
Select-Object Average
} -ComputerName $comp -Credential $authType
return $Cpu_Average.Average
}
workflow Test-Workflow {
foreach -parallel ($serv1 in $Servers) {
$Size = Get_FreeSpace -authType $cred -comp $serv1
$Cpu_Avg = Get_CPUAverage -authType $cred -comp $serv1
Write-Host $Size
}
}
Test-Workflow
Write-Host $Size
$Size is not returning anything if I use -parallel loop.
should pass $Servers as param as shown below:
workflow Test-Workflow {
param($Servers)
foreach -parallel ($serv1 in $Servers) {
$Size = Get_FreeSpace -authType $cred -comp $serv1
$Cpu_Avg = Get_CPUAverage -authType $cred -comp $serv1
Write-Host $Size
}
}
Test-Workflow $Servers
Alternatively, invoke-command runs in parallel with multiple computers:
invoke-command comp1,comp2,comp3 { sleep 5; "done $env:computername" }

Output from invoke-command not returning

I have the following scriptblock:
$scriptblock = {
$regpath = "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp"
$securitylayer = Get-ItemProperty -Path $regpath -Name SecurityLayer -ErrorAction SilentlyContinue
If (!($securitylayer) -or ($securitylayer.securitylayer -ne '0')) {
Write-Host -ForegroundColor Yellow "Regkey not present or value not 0. Creating/setting to 0"
#Commented out for testing purposes
#Set-ItemProperty -Path $regpath -Name SecurityLayer -Value 0
}
Else {Write-Host -ForegroundColor green "Regkey present and set to 0. Skipping."}
}
that I pass to a PSSession on a remote machine running Server 2003 SP2:
$computername = 'computer'
$pssession = New-PSSession -ComputerName $computername -Name $computername
Invoke-Command -Session $pssession -ScriptBlock {$scriptblock}
But i don't see any output.
I've also tried
write-output
but still don't see any output.
I saw another post that suggested doing the following, however nothing was returned:
$scriptblock = {
$regpath = "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp"
$securitylayer = Get-ItemProperty -Path $regpath -Name SecurityLayer -ErrorAction SilentlyContinue
If (!($securitylayer) -or ($securitylayer.securitylayer -ne '0')) {
new-object pscustomobject –property #{Result = "Regkey not present or value not 0. Creating/setting to 0"}
#Commented out for testing purposes
#Set-ItemProperty -Path $regpath -Name SecurityLayer -Value 0
}
Else {new-object pscustomobject –property #{Result = "Regkey present and set to 0. Skipping."}}
}
$computername = 'computer'
$pssession = New-PSSession -ComputerName $computername -Name $computername
$results = Invoke-Command -Session $pssession -ScriptBlock {$scriptblock}
$results.result
Code runs as expected when run on machine.
You are wrapping your scriptblock in a scriptblock, so it's not actually executing the script block. Just remove the {} from around the {$scriptblock}:
Invoke-Command -Session $pssession -ScriptBlock $scriptblock