nested scriptblocks in a powershell remote session - powershell

I am trying to run a script block on a remote machine, but i don't to be prompted for credentials, i want to pass them in the script.
Some commands may but the commands i want to run are access denied unless i provide the credential.
for example this command can work:
Invoke-Command -Session $session -ErrorAction Stop -ErrorVariable $Error -Scriptblock {ls }
but this wont work unless -credential is passed (Invoke-Command on target)
Invoke-Command -Session $session -ErrorAction Stop -ErrorVariable $Error -Scriptblock {Invoke-Command -computername $Env:COMPUTERNAME -Credential $Cred -ScriptBlock {ls} }
the same way what i want to achieve causes access denied problem (starting a process)
Invoke-Command -Session $session -ErrorAction Stop -ErrorVariable $Error -Scriptblock {[System.Diagnostics.Process]::Start("C:\Myprocess.exe", $localArgs, "UserName", $credential.Password, "MyDomain")}

Invoke-Command -Session $session -ErrorAction Stop -ErrorVariable $setError -Scriptblock {$Domain = "domain";$PassSec = ConvertTo-SecureString $( "password") -AsPlainText -Force ; $Cred = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $($domain + "\" + "userName"),$passSec; Invoke-Command -computername $Env:COMPUTERNAME -Credential $Cred -ScriptBlock {C:\Myprocess.exe } }

Related

Invoke-Command with remote session: Cannot validate argument on parameter

I wrote a script to restart a few ASP.NET websites on a remote server:
$computerName = #...
$password = #...
$secureStringPassword = ConvertTo-SecureString -AsPlainText -Force -String $password
$userName = #...
$credential= New-Object System.Management.Automation.PSCredential ($userName, $secureStringPassword)
$websiteNames = #..., #..., #...
Get-PSSession -ComputerName $computerName -Credential $credential | Remove-PSSession
$psSession = New-PSSession -ComputerName $computerName -Credential $credential
Invoke-Command -Session $psSession -ScriptBlock { $websiteNames | foreach{ Stop-Website -Name $_ } }
Invoke-Command -Session $psSession -ScriptBlock { $websiteNames | foreach{ Start-Website -Name $_ } }
$psSession | Remove-PSSession
For some reasons my Invoke-Command do not run properly, I have the following error message:
Cannot validate argument on parameter 'Name'. The argument is null. Provide a valid value for the argument, and then try running the command again.
When the commands are run after an Enter-PSSession it works fine within a -ScriptBlock it kinda mess up the -Name parameter, any idea how to fix that up?
The remote session cannot access the variables you have defined locally. They can be referenced with $using:variable
Invoke-Command -Session $psSession -ScriptBlock { $using:websiteNames | foreach{ Stop-Website -Name $_ } }
Invoke-Command -Session $psSession -ScriptBlock { $using:websiteNames | foreach{ Start-Website -Name $_ } }
More information in the about_remote_variables help:
get-help about_remote_variables -Full
Actually just needed to pass the arguments to the -ArgumentList of the -ScriptBlock and use $args to reference to it within the function block:
Invoke-Command -Session $psSession -ScriptBlock { $args | foreach{ Stop-Website -Name $_ } } -ArgumentList $websiteNames
Invoke-Command -Session $psSession -ScriptBlock { $args | foreach{ Start-Website -Name $_ } } -ArgumentList $websiteNames

Powershell Invoke-Command with arbitrary ScriptBlock

I have the following command which executes successfully on a remote Windows server.
Invoke-Command -ComputerName $ComputerName -UseSSL -SessionOption $sessionOptions -Credential $cred -ScriptBlock
{Start-Service "Test Service"}
I am attempting to pass in the script block as a variable so that I can execute any arbitrary command on the particular server, but I can't seem to pass the ScriptBlock argument successfully. The code executes without any errors, but does not start the remote service.
$ScriptBlock = Start-Service "Test Service"
Invoke-Command -ComputerName $ComputerName -UseSSL -SessionOption $sessionOptions -Credential $cred -ScriptBlock
{$args[0]} -ArgumentList $ScriptBlock
Enclose the code in {} to define a scriptblock literal when assigning it to your $ScriptBlock variable, then pass that as the argument to the -ScriptBlock parameter:
$ScriptBlock = { Start-Service "Test Service" }
Invoke-Command -ScriptBlock $ScriptBlock -ComputerName $ComputerName -UseSSL -SessionOption $sessionOptions -Credential $cred

How to get local computer name after New-PSSession -Computername?

I am getting the below error, please advise how to fix this error for null-valued expression
You cannnot call a method on a null-valued expression
+CategoryInfo : InvalidOoperation: (:)[], RuntimeException
+FullyQualifiedErrorId: InvokeMethodonNull
+PSComputerName: DC1
Code below
function myfunction (){
$remoteserver = 'DC1'
$Session = New-PSSession -Computername $remoteserver -Credential $Cred
Import-Module ActiveDirectory
$local= $env:COMPUTERNAME
Invoke-Command -ComputerName $remoteserver -Credential $cred -ScriptBlock
{$using:local
if($local.substring(5,3) -imatch "Sys") {
Get-ADComputer $local | Move-ADObject -Targetpath "ou=PRD,ou=Servers,dc=com,dc=Companycorp,dc=net"}
}
} #end function
Invoke-Command -ComputerName $remoteserver -ScriptBlock ${Function:myFunction}
What you're looking for is the $using: scope. If you define variables that you want to use in your remote execution, you need to access them like:
$PC = $env:ComputerName
Invoke-Command -Computer DC01 -ScriptBlock { $using:PC <# logic #> }
If you mean you want to remote into DC01 to run commands against localhost, you're going to run into the second-hop problem due to Kerberos.
Update: Your new example looks pretty convoluted. Here's an example that should work:
$MyPC = $env:ComputerName
$Session = New-PSSession -Credential (Get-Credential) -ComputerName 'DC1'
Invoke-Command -Session $Session -ScriptBlock {
Import-Module -Name 'ActiveDirectory'
$PC = $using:MyPC
If ($PC.Substring(5,3) -eq 'sys')
{
Get-ADComputer -Identity $PC |
Move-ADObject -TargetPath 'ou=PRD,ou=Servers,dc=com,dc=Companycorp,dc=net'
}
}
What I think you're asking is 'how do I open a session on a remote pc, but then still run commands on my local PC'. If that's so, then let's walk through it.
First, we can open a remote connection to another computer in PowerShell by creating a new PSSession, as you're doing here:
$session = New-PSSession -Computername DC01 -Credential $cred
You can then either step into the remote computer wholly using Enter-PSSession, or just send individual commands to the remote computer using:
Invoke-Command -ScriptBlock {#Commands to run on the remote PC}`
-Session $session
Once you enter the remote PC, you can return to your own PC using the Exit-PSSession command.
#Enter Remote PC
Enter-PSSession $session
DC01> hostname
*DC01*
#Step out of Remote PC
Exit-PSSession
PS> hostname
*YOURPCNAME*
If this isn't what you want to do, let me know and we'll get you sorted.
You have to use Invoke-Command :
$session = New-PSSession -Computername DC01 -Credential $cred
Invoke-Command -Session $session -ScriptBlock {
$remoteComputerName = $env:computername
}

Running Batch Script on remote Server via PowerShell

I need to connect to some remote servers from a client (same domain as the servers) once connected, I need to run a batch file:
I've done so with this code:
$Username = 'USER'
$Password = 'PASSWORD'
$pass = ConvertTo-SecureString -AsPlainText $Password -Force
$Cred = New-Object System.Management.Automation.PSCredential -ArgumentList $Username,$pass
try {
Invoke-Command -ComputerName "SERVER1" -Credential $Cred -ScriptBlock -ErrorAction Stop {
Start-Process "C:\Users\nithi.sundar\Desktop\Test.bat"
}
} catch {
Write-Host "error"
}
This script does not give any errors, but it doesn't seem to be executing the batch script.
any input on this would be greatly appreciated.
Try replacing
invoke-command -computername "SERVER1" -credential $Cred -ScriptBlock -ErrorAction stop { Start-Process "C:\Users\nithi.sundar\Desktop\Test.bat" }
with
Invoke-Command -ComputerName "Server1" -credential $cred -ErrorAction Stop -ScriptBlock {Invoke-Expression -Command:"cmd.exe /c 'C:\Users\nithi.sund
ar\Desktop\Test.bat'"}
It's not possible that the code you posted ran without errors, because you messed up the order of the argument to Invoke-Command. This:
Invoke-Command ... -ScriptBlock -ErrorAction Stop { ... }
should actually look like this:
Invoke-Command ... -ErrorAction Stop -ScriptBlock { ... }
Also, DO NOT use Invoke-Expression for this. It's practically always the wrong tool for whatever you need to accomplish. You also don't need Start-Process since PowerShell can run batch scripts directly:
Invoke-Command -ComputerName "SERVER1" -ScriptBlock {
C:\Users\nithi.sundar\Desktop\Test.bat
} -Credential $Cred -ErrorAction Stop
If the command is a string rather than a bare word you need to use the call operator, though:
Invoke-Command -ComputerName "SERVER1" -ScriptBlock {
& "C:\Users\nithi.sundar\Desktop\Test.bat"
} -Credential $Cred -ErrorAction Stop
You could also invoke the batch file with cmd.exe:
Invoke-Command -ComputerName "SERVER1" -ScriptBlock {
cmd /c "C:\Users\nithi.sundar\Desktop\Test.bat"
} -Credential $Cred -ErrorAction Stop
If for some reason you must use Start-Process you should add the parameters -NoNewWindow and -Wait.
Invoke-Command -ComputerName "SERVER1" -ScriptBlock {
Start-Process 'C:\Users\nithi.sundar\Desktop\Test.bat' -NoNewWindow -Wait
} -Credential $Cred -ErrorAction Stop
By default Start-Process runs the invoked process asynchronously (i.e. the call returns immediately) and in a separate window. That is most likely the reason why your code didn't work as intended.

invoke-expression inside scriptblock of invoke-command not working

I've got the following script
$name = (Invoke-Command -ComputerName "STW111" -Credential $cred -ScriptBlock { Invoke-Expression "C:\PSS\User Tool\UserTool.exe"} -AsJob).Name
Wait-Job -Name $name
This not working, however, if I move the usertool to c:\pss\, it works fine.
$name = (Invoke-Command -ComputerName "STW111" -Credential $cred -ScriptBlock { Invoke-Expression "C:\PSS\UserTool.exe"} -AsJob).Name
Wait-Job -Name $name
I really need to get to grips with escaping in Powershell.
Any ideas?
TIA
try this:
Invoke-Expression "& 'C:\PSS\User Tool\UserTool.exe'"