How to run multiple commands via Invoke-Command on remote server - powershell

In the below example, only the Get-Process in my scriptblock is being executed. "deh" does not print for some reason
Invoke-Command -ComputerName mycomputer -Credential $mycreds -ScriptBlock {
Get-Process
Write-Host "deh"
}
If I remove -ComputerName and execute on local, then it runs both commands just fine.
EDIT:
Here I am trying to execute IIS cmdlets against remote server. The following command works
Invoke-Command -ComputerName mycomputer -ScriptBlock {
Trace-Command CommandDiscovery {
Import-Module webAdministration
Start-WebAppPool -Name DefaultAppPool
} -PSHost
}
but this does not work
Invoke-Command -ComputerName mycomputer -ScriptBlock {
Import-Module webAdministration
Start-WebAppPool -Name DefaultAppPool
}
what is special about Trace-Command that it is helping Start-WebAppPool to work? this is really odd and I can't explain why this functionality..

No, the Invoke-Command cmdlet takes a scriptblock where you can put multiple commands. You should also be able to see the Write-Host output.

You can do a Trace-Command on the remote machine via Invoke-Command to see what is happening. I'm not able to reproduce this.
Invoke-Command -ComputerName mycomputer -Credential $Creds -ScriptBlock { Trace-Command CommandDiscovery {get-process;write-host 'deh'} -PSHost }

Try to separate the commands using a semicolon:
Invoke-Command -ComputerName mycomputer -Credential $mycreds -ScriptBlock {
Get-Process ;
Write-Host "deh"
}

Related

Logging scripts from a non-interactive session

I've been searching for a way of logging a script that is run in a powershell remote session that is similar to what you get from using Start-Transcript. When I try getting a transcript from a remote session, the transcript file gets created, but there is nothing in the file.
$servers = "ServerA"
$session = New-PSSession -ComputerName $servers -Credential $creds -Authentication Default -ErrorAction Stop
Invoke-Command -Session $session -ScriptBlock {
Start-Transcript -OutputDirectory D:\LOGS
Set-Location c:\scripts
Get-ChildItem
Stop-Transcript
Exit-PSSession
}
Remove-PSSession $session
The Transcript file is there, but none of the commands get logged. I know that this is because the scriptblock that is executed on the remote system is a non-interactive session.
What does everyone else do to log any success / failures in their remote scripts?
You don't have to write logfiles on the remote machine. You can collect all information on the caller machine, e.g.
$servers = "ServerA"
$session = New-PSSession -ComputerName $servers -Credential $creds -Authentication Default -ErrorAction Stop
$result = Invoke-Command -Session $session -ScriptBlock {
#Store result into variable
$data = Get-ChildItem -path c:\scripts
#return variable
return $data
}
Remove-PSSession $session
$result on the caller machine will contain the data (objects incl. the hostname of the remote machine) returned from the remote machine.

Redirect output of Import-Module within ScriptBlock of Invoke-Command

A module I am importing has several Write-Host commands that I wish to suppress (redirect to NULL).
This works great when I run it directly on a machine:
Import-Module 'path\to\module\module.ps1' 2>&1 > $null
When running the exact same on a remote host using Invoke-Command, the redirect is ignored and all the output from the module shows up:
Invoke-Command -ComputerName $server -Credential $cred -ScriptBlock {
Import-Module 'path\to\module\module.ps1' 2>&1 > $null
}
I've tried different ways of re-direct (i.e. Out-Null, etc), all with the same result.
You could use 6>> $null .
so:
Invoke-Command -ComputerName $server -Credential $cred -ScriptBlock {
Import-Module 'path\to\module\module.ps1' 6>> $null
}
This is the "Example 5: Suppress output from Write-Host" provided by Microsoft, modified accordingly to "about_Operators".

PowerShell run bat from location on my computer on remote computer

I need to run a BAT file on some servers
Because of the amount of many servers I avoid copying the file on any server
I have the file on my computer and I try to access it remotely
$CMDCOMMAND = "\\Mycomp\c$\file.bat"
Invoke-Command -ComputerName $Hostname -Credential $Cred -ScriptBlock {
Start-Process cmd.exe "/c $CMDCOMMAND
}
Invoke-Command -Computer $Hostname -Credential $Cred -FilePath $CMDCOMMAND
should work as #Ansgar Wiechers mentioned.
I doubt you have set $CMDCOMMAND = "\\Mycomp\c$\file.bat" and tried. It should be local path when you pass it to -FilePath
$CMDCOMMAND = "c:\file.bat"
Invoke-Command does not work with a variable defined outside the ScriptBlock. You need to use the ArgumentList parameter. Something like this should work, although I have not tested it:
$CMDCOMMAND = "\\Mycomp\c$\file.bat"
Invoke-Command -ComputerName $Hostname -Credential $Cred -ScriptBlock {
param($ARGLIST) Start-Process cmd.exe "/c $ARGLIST"
} -ArgumentList $CMDCOMMAND

How to use invoke-command in powershell, to run a script on remote machine

Is it possible to use Invoke-Command in PowerShell to run a script on a remote machine?
I have tried :
Invoke-Command -ComputerName $MyPC -Credential $mycreds -ScriptBlock {
& "C:\Users\MyPC\Desktop\scripts\Script1.ps1"
}
which returns
script1.ps1 is not recognized as the name of a cmdlet
The scenario here is, I have some scripts on a remote folder, and I need to use Invoke-Command or some other ways to run the script on a remote machine.
Also, how to write if I want to pass some parameters for script1.ps1? Thanks in advance!
Instead of this:
Invoke-Command -ComputerName $MyPC -Credential $mycreds -ScriptBlock {& "C:\Users\MyPC\Desktop\scripts\Script1.ps1"}
Try this:
Invoke-Command -ComputerName $MyPC -Credential $mycreds -FilePath C:\Users\MyPC\Desktop\scripts\Script1.ps1
to avoid confusion with filepaths on local machines/remote machines; i always run stuff from smb-shares; you can enter UNC as filepath... eg:
-FilePath \server\Netscripts\script.ps1

How to remote to the computer itself with powershell

Now I need to run scripts on remote machines to do some deployment work by using:
Invoke-Command -ComputerName $hostName -Credential $cred -ScriptBlock $scriptBlock
And if the $hostName is the computer that calls this command, it reports:
message : Access is denied. For more information, see the about_Remote_Troubleshooting Help topic.
+ CategoryInfo : OpenError: (myMachineName:String) [], PSRemotingTransportException
+ FullyQualifiedErrorId : AccessDenied,PSSessionStateBroken
I want to run the command in a unified way no matter it is a remote or the local machine.
Updated:
I'm using using a machine in Azure. this command works:
Invoke-Command -ComputerName XXX -Credential $cred -ScriptBlock $scriptBlock
But this one not:
Invoke-Command -ComputerName XXX.cloudapp.net -Credential $cred -ScriptBlock $scriptBlock
Can anybody help?
Pass localhost as the computer name:
Invoke-Command -ComputerName localhost -Credential $cred -ScriptBlock $scriptBlock
Using the hostname of the computer should also work, as mentioned by #CB. in the comments to the question:
Invoke-Command -ComputerName $env:COMPUTERNAME -Credential $cred `
-ScriptBlock $scriptBlock
If you need the FQDN elsewhere and just want to remove the domain part for the Invoke-Command statement you can remove it like this:
Invoke-Command -ComputerName ($hostname -replace '\..*') -Credential $cred `
-ScriptBlock $scriptBlock
To handle the target computer name depending on whether or not the given hostname is the name of the local host you could do something like this:
$server = if (($hostname -replace '\..*') -eq $env:COMPUTERNAME) {
'localhost'
} else {
$hostname
}
Invoke-Command -ComputerName $server -Credential $cred -ScriptBlock $scriptBlock
Note that either way WinRM must be enabled on the local computer for this to work.