Powershell | second Invoke Using:Variable - powershell

i have a simple question. I want to use a variable in an invoke-command and pass this to the second invoke-command. In the second invoke-command the variable is empty
here is my code:,
$WaitSeconds = 1234
Invoke-Command -ComputerName $remote -Credential $cred -ScriptBlock {
$computer = dsquery computer "DC=domain,DC=local" -o rdn
$computers = $computer -replace ('"', '')
write-host $computers
foreach ($computer in $computers) {
if ($computer -notmatch "AZUREADSSOACC")
{
Invoke-Command -ComputerName $computer -Credential $using:cred -ScriptBlock {
#### here script
shutdown -s -t $using:waitseconds
}
}
}
}

In the second invoke-command the variable is empty
That's because the variable doesn't exist inside the calling session (the first Invoke-Command call's execution context).
Make sure you first instruct PowerShell to copy the variable to the "outer" Invoke-Command call:
$WaitSeconds = 1234
Invoke-Command {
# PowerShell will now copy the $WaitSeconds variable value from the calling scope to this remote session
$WaitSeconds = $using:WaitSeconds
# ...
Invoke-Command {
# This will now resolve the variable value correctly
shutdown -s -t $using:WaitSeconds
}
}

i got it
my solution is:
$WaitSeconds = 1234
Invoke-Command {
param($WaitSeconds)
$WaitSeconds = $WaitSeconds
# ...
Invoke-Command {
param($WaitSeconds)
shutdown -s -t $WaitSeconds
} -ArgumentList $WaitSeconds
} -ArgumentList $WaitSeconds

Related

Powershell | get a value from 2 nested invoke commands

i want to transfer the values from the invoke commands to local. I have problems to get the values from the second invoke command. I want $computers and $tasks in the textbox. Any Ideas? I have tried with return but then i can only get the values from first invoke command.
EDITED:
$session = New-PSSession -ComputerName $remote -Credential $cred
Invoke-Command -Session $session -ScriptBlock {
### get all computers in Domain ###
$computers = dsquery computer "DC=kanzlei,DC=local" -o rdn
Write-Host ("In dieser Domäne gibt es die folgenden Server:")
write-host $computers
#configure all computers
foreach($computer in $computers) {
$session3 = New-PSSession -ComputerName $remote -Credential $cred_session
Invoke-Command -Session $session3 -ScriptBlock {
write-host "Tasks for $env:computername gonna be activated"
#### acitivate tasks ####
$tasks = Get-ScheduledTask -TaskPath "\RA-MICRO_Update_Routine\" | Enable-ScheduledTask | FL Taskname,State }
write-host "$tasks"
}
}
}
##### I want vriable $Computers and $Tasks here on Local ####
do anything with $tasks
do anything with $computers

PowerShell Exit out of the whole script not Just the Invoke-Command

I have a script that is currently monitoring a couple of windows services on different VMs. If the service is stopped, it will attempt to start the service.
I have added a $LoopCounter to stop the script it it loops to many time as to not fall into an infinite loop if the service cannot be started for what ever reason.
This is all inside a Invoke-Command that runs some code on the remote VMs. I have used Exit to stop the script running but it does not seem to be in the right scope of things and it stops the Invoke-Command but not the whole script.
Script:
Invoke-Command -ComputerName VM1, VM2, VM3 -Credential $Cred -ArgumentList $ServiceList -ScriptBlock {
Foreach ($Service in $Using:ServiceList) {
$C = [System.Net.Dns]::GetHostName()
$S = Get-Service -Name $Service
while ($S.Status -ne 'Running') {
# Code...
$LoopCounter++
If($LoopCounter -gt 2) {
Exit
}
}
}
}
You could have the scriptblock return a value and check for that.
The example below has the returned value 1 if the script should exit as a whole:
$result = Invoke-Command -ComputerName VM1, VM2, VM3 -Credential $Cred -ArgumentList $ServiceList -ScriptBlock {
Foreach ($Service in $Using:ServiceList) {
$C = [System.Net.Dns]::GetHostName()
$S = Get-Service -Name $Service
while ($S.Status -ne 'Running') {
# Code...
$LoopCounter++
If($LoopCounter -gt 2) {
return 1 # return a value other than 0 to the calling script
Exit # exit the scriptblock
}
}
}
}
# check the returned value from Invoke-Command
# if it is not 0 (in this example), exit the whole script
if ($result) { exit }
Hope that helps

how to pass command line parameters to invoked session in powershell 2.0

How can i pass command line parameters to a session which is invoked using 'invoke-command' in powershell 2.0
my script:
param(
[string]$hostname = 'my_server_name'
)
function createSession($hostname){
return New-PSSession -ComputerName $hostname -Credential $env:UserDomain\$env:UserName
}
$session = createSession $hostname
invoke-command -Session $session -ScriptBlock {
write-host $hostname
write-host $using:hostname
write-host $script:hostname
write-host '**test text**'
}
Exit-PSSession
Output: (I'm getting empty string if i print the parameter value directly.)
**test text**
use param block
$hostname = $env:computername
Invoke-Command -ScriptBlock { param($hostname)
Write-OutPut $hostname
} -ArgumentList $hostname
param(
[string]$hostname = 'my_server_name'
)
function createSession($hostname){
return New-PSSession -ComputerName $hostname -Credential $env:UserDomain\$env:UserName
}
$session = createSession $hostname
invoke-command -Session $session -ScriptBlock {
$hostname=$using:hostname
or
$hostname=$script:hostname
write-host $hostname
write-host '**test text**'
}
Exit-PSSession
Hope any one of the above helps,If Not Please look at the concept of scoping variables in powershell,May be they will help
Powershell variable scoping

PowerShell passing DateTime variable to Set-Date

Here is code:
$computerList = "localhost", "luna"
$user = Get-Credential powershell
$date = Get-Date
foreach ($computer in $computerList) {
if ($computer -eq "localhost") { $session = New-PSSession -ComputerName $computer }
else { $session = New-PSSession -ComputerName $computer -Credential $user }
Invoke-Command -Session $session -ScriptBlock {
Set-Date -Date $date
}
}
I'm getting this error:
Cannot bind argument to parameter 'Date' because it is null.
Working in console line by line it works but when running script variable $date is null like error says.
Why is variable $date null?
It shouldn't work either way, you are referring to local variable when executing command in a remote session, you should be calling the variable like this:
Invoke-Command -Session $session -ScriptBlock {
Set-Date -Date $using:date
}
More on remote variable.

Remote Registry using Enter-PSSession

I am trying to read strings in a remote registry. When I run the script I am working on, it connects to the workstation in the list, but it only reads the local computer when running, not the remote. any Ideas?
#create open dialog box
Function Get-FileName($initialDirectory)
{
[void] [Reflection.Assembly]::LoadWithPartialName( 'System.Windows.Forms' );
$d = New-Object Windows.Forms.OpenFileDialog;
$d.ShowHelp = $True;
$d.filter = "Comma Separated Value (*.csv)| *.csv";
$d.ShowDialog( ) | Out-Null;
$d.filename;
}
# Set Variables with arguments
$strFile = Get-FileName;
$strComputer = Get-Content $strFile;
$date = Get-Date -Format "MM-dd-yyyy";
$outputFile = "C:\PowerShell\Reports";
$cred = Get-Credential
foreach($computer in $strComputer)
{
Enter-PSSession $computer -Credential $cred
Set-Location HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Reliability
$systemInfo = Get-Item -Name LastComputerName
Write-Host $systemInfo
}
foreach($computer in $strComputer)
{
Enter-PSSession $computer -Credential $cred
..
..
}
The above code won't work. Enter-PSSession is not for using in a script. Anything written after that in a script won't run.
Instead, use Invoke-Command and pass rest of the script block as a parameter value. For example,
foreach ($computer in $strComputer) {
Invoke-Command -ComputerName $computer -Credential $cred -ScriptBlock {
Set-Location HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Reliability
$systemInfo = Get-Item -Name LastComputerName
Write-Host $systemInfo
}
}
As the comments already explained, Enter-PSSession is for interactive use. To read remote registry entries, there are several ways.
Use plain reg.exe, it works well enough. Like so,
foreach($computer in $strComputers) {
reg query \\$computer\hklm\software\Microsoft\Windows\CurrentVersion\Reliability /v LastComputerName
}
Use PSSessions. Create a session and Invoke-Command to read registry. Like so,
function GetRegistryValues {
param($rpath, $ivalue)
Set-Location $rpath
$systemInfo = (Get-ItemProperty .).$ivalue
Write-Host $systemInfo
}
$session = New-PSSession -ComputerName $computer
Invoke-Command -Session $session -Scriptblock ${function:GetRegistryValues} `
-argumentlist "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Reliability",`
"LastComputerName"
Remove-PSSession $session
Use .Net classes, Microsoft.Win32.RegistryKey. Like so,
$sk = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine, $server)
$k = $sk.opensubkey("SOFTWARE\Microsoft\Windows\CurrentVersion\Reliability", $false)
write-host $k.getvalue("LastComputerName")