How to run script on remote pc - powershell

I am trying to run a powershell script on remote pc . if i put the path in variable it does not run, but if i put the path as string it works. Not sure why.
This works
Invoke-Command -computername $serverName -scriptblock {& ("C:\_Project\test.ps1") }
This does not work
$server = "test"
$script = "C:\_Project\test.ps1"
Invoke-Command -computername $server -scriptblock {& ( $script) }
I would like to get the 2nd one working

Variables need to be passed to script blocks as arugments or they won't be available in the scriptblock. Here is how to do it.
$server = "test"
$script = "C:\_Project\test.ps1"
Invoke-Command -computername $server -ArugmentList $Script -scriptblock {
Param ($Script)
& ( $script)
}

Try this:
$server = "test"
$script = [ScriptBlock]::Create("& C:\_Project\test.ps1")
Invoke-Command -computername $server -scriptblock $script

Related

Problem with test-path on computer from another domain

Im trying to test a remote folder in a computer from another domain with -credential
This command works fine:
Invoke-Command -ComputerName "server" -credential domain\user -ScriptBlock {Test-Path -Path "\\server\s$\temp"}
But if i use it in a script fails:
$servers = Get-Content "servers.txt"
$Path = "\\D$\Temp"
$cred = "domain\user"
ForEach ($server in $servers) {
if (invoke-command -computername $server -credential $cred -ScriptBlock {Test-Path -Path "\\$server\$Path"})
}
PD: All this option works in a server of my domain without specify another credentials.
Besides the syntax issue with missing the script block after your if statement, this should work as long as you specify the variables as remote ones. Use $using or pass it as an argument with -ArgumentList.
$servers = Get-Content "servers.txt"
$Path = "\\c$\Temp"
$cred = "domain\user"
ForEach ($server in $servers) {
if (
invoke-command -computername $server -ScriptBlock {
Test-Path -Path "\\$using:server\$using:Path"
}
) { <#do code here#> }
}
If you run the shell with the proper credentials to begin with, all youd have to do is use Test-Path directly but I understand that you'd like to try using the -Credential parameter.

Invoke-Command Doesn't Run with Parameters

I'm trying to run Invoke-Command within a PowerShell script to run scripts on remote servers. It retrieves the computer names and scripts to run from an XML file. Code sample is below. The script executes but nothing on the remote server is being run. I've tried 2 different ways to run Invoke-Command.
[string] $computer = "lumen"
[string] $scriptBlock = "cd C:\Scripts\Update-Apps; ./Update-Apps"
$session = New-PSSession -ComputerName $computer
Invoke-Command -Session $session -ScriptBlock { $scriptBlock }
#Invoke-Command -ComputerName $computer -ScriptBlock { $scriptBlock }
What am I doing wrong with Invoke-Command?
Thanks!
You are passing in a scriptblock with a string. When it will call it, it will basically have the same effect as writing $scriptBlock in your terminal. You have to actually execute the string in the scriptblock. You could use Invoke-Expression.
[string] $computer = "lumen"
[scriptblock] $scriptBlock = { "cd C:\Scripts\Update-Apps; ./Update-Apps" | Invoke-Expression }
$session = New-PSSession -ComputerName $computer
Invoke-Command -Session $session -ScriptBlock $scriptblock
Or you could write directly your command as PowerShell code in the scriptblock.
[string] $computer = "lumen"
[scriptblock] $scriptBlock = { cd C:\Scripts\Update-Apps; ./Update-Apps }
$session = New-PSSession -ComputerName $computer
Invoke-Command -Session $session -ScriptBlock $scriptblock
It doesn't have to be a string.

Executing program on remote with Powershell

I'm having trouble executing a program on a remote server. This is my command
$appCommand = "`"c:\SIDApps\{0}\{1}.exe`"" -f $destinationDirectory, $processToKill
Invoke-Command -ComputerName $remoteComputer -Credential $credentials -ScriptBlock { $args[0] } -ArgumentList $appCommand
That prints out "c:\SIDApps\FFMBC_Drone\GCUKTransCodeServiceFFMBCApp.exe" (Including the quotes) in the output window, but does not actually execute the program
If you only output $args[0] in the ScriptBlock it will only display the path not run the command.
Have you tried this ?
$appCommand = "c:\SIDApps\{0}\{1}.exe" -f $destinationDirectory, $processToKill
Invoke-Command -ComputerName $remoteComputer -Credential $credentials -ScriptBlock { Start-Process $args[0] } -ArgumentList $appCommand

How to start remotely process in PowerShell

I have a problem, I have a script which:
Connect with PSSession (I use PSSession with admin account)
Stop 2 process
Do change on them files
Start the 2 process (Problem here)
I want to start process on server, so i'm connect with PSSession (No problem)
I do Invoke-Command :
# $pathProg path to my program
Invoke-Command -session $mySession -command {Start-Process $($args[0])} -ArgumentList $pathProg
But it does nothing (I verify with VNC)
I do Invoke-Command too :
# $pathProg path to my program
Invoke-Command -session $mySession -command {&$($args[0])} -ArgumentList $pathProg
It lauch the program (Good) but my script wait the end program (Not good)
Anyone have an idea ?
Thanks
You can try using WMI:
$command = "notepad.exe"
$process = [WMICLASS]"\\$CompName\ROOT\CIMV2:win32_process"
$result = $process.Create($command)
If you need passing credentials:
$cred = get-credential
$process = get-wmiobject -query "SELECT * FROM Meta_Class WHERE __Class = 'Win32_Process'" -namespace "root\cimv2" -computername $CompName -credential $cred
$results = $process.Create( "notepad.exe" )
$pathProg may be not be available within the script block which gets run eventually. You might want to pass it as an argument to the script block
Invoke-Command -session $mySession -command { param($progPath) ... } -argumentlist $progPath
Not that the outer -argumentlist, passes the arguments to the scriptblock.
Have you tried building the command as a string locally, then passing it to the Invoke-Command script as a ScriptBlock?
$remoteSession = New-PSSession -ComputerName 'MyServer'
$processName = 'MyProcess'
$command = 'Start-Service ' + $processName + ';'
Invoke-Command -Session $remoteSession `
-ScriptBlock ([ScriptBlock]::create($command))
Remove-PSSession $remoteSession
If you want feedback from the remote server then you can get the output via Write-Output, like this:
$command = 'Start-Service ' + $processName + ' | Write-Output ;'

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")