Passing Powershell variables to batch files [duplicate] - powershell

This question already has answers here:
How do I pass variables with the Invoke-Command cmdlet?
(3 answers)
Closed 3 years ago.
I have some problem passing the PowerShell variables to Invoke-Command (running CMD /C). The problem is, that the $script_location parameter is empty.
My script creates a batch file on an UNC path with an unique name (20190423T1152100840Z.bat) with some commands in it. At the end, I would like to run this generated batch file on a server.
$datum = Get-Date -Format FileDateTimeUniversal
$script_location = "\\uncpath\batchfile_$datum.bat"
$Username = 'user'
$Password = 'pass'
$pass = ConvertTo-SecureString -AsPlainText $Password -Force
$Cred = New-Object System.Management.Automation.PSCredential -ArgumentList $Username,$pass
Add-Content $script_location " preferences_manager -u=user -p=pass -target=$env:username"
Invoke-Command -ComputerName "SERVERNAME" -Credential $cred -ScriptBlock {
Invoke-Expression -Command:"cmd /c $script_location"
}
The expected result should be that the Invoke-Command runs the $script_location batch file.
Currently the result is that that the $script_location variable is empty.
Any clue on how to do that?

The easiest way to pass a variable into a ScriptBlock is by prefixing its name with the using: scope.
Invoke-Command -ComputerName "SERVERNAME" -Credential $cred -ScriptBlock {
Invoke-Expression -Command:"cmd /c $using:script_location"
}
You can also pass it as an argument:
Invoke-Command -ComputerName "SERVERNAME" -Credential $cred -ScriptBlock {
Param($ScriptLocation)
Invoke-Expression -Command:"cmd /c $ScriptLocation"
} -ArgumentList $script_location

Related

Passing Credentials In PowerShell multi line scriptblock

I have passed credentials before using a credential parameter in my Scriptblock and passing the value via an argument. I expect the size of my Scriptblock to grow so I am using a here string to keep it clean then I convert the string into a Scriptblock. How do I add a credential parameter and argument to my example below. I know the $credential value I use to get my remote session below has the necessary priveleges to get the file I want as I have tested it on the remote machine. So if possible I would like to pass this same credential.
$user = 'MyDomain\username'
$password = ConvertTo-SecureString 'mypassword' -asplaintext -force
$credential = New-Object -typename System.Management.Automation.PSCredential -ArgumentList $user, $password
try {
$s = New-PSSession -ComputerName MyRemoteComputer -Credential $credential
$remoteCommand = #"
New-PSDrive -Name 'P' -PSProvider 'FileSystem' -Root '\\main-server\Folders\DevOps\Projetcs\Juniper'
Get-Item -Path P:\V1.6\InstallFiles\Install.bat
"#
$scriptBlock = [Scriptblock]::Create($remoteCommand)
$status = Invoke-Command -Session $s -ScriptBlock $scriptBlock
Write-Host $status
Exit-PSSession -Session $s
}
catch {
#TODO Add exception handling
}

PowerShell passing arguments to Invoke-Command in a foreach loop

Why does PowerShell asks me for Credentials to access a remotecomputer, after I already put in the password for my $PW variable and created the correct PSCredentials with it? The other Issue I have is that Start-Process can't find the FilePath specified (Null or empty).
I guess those two errors are because of the same error, it has to be because my Variable-Values aren't passed to the foreach loop. As you can see, I tried to achieve a solution by trying the -argumentlist parameter, but it doesn't work. What Am I doing wrong?
function Install-Exe {
param(
[string[]]$ComputerName,
[string]$UNCexepath,
[string[]]$exeargs
)
$Admin = "domain\admin"
$PW = Read-Host "Enter Password" -AsSecureString
$cred = New-Object System.Management.Automation.PSCredential -argumentlist $Admin, $PW
foreach ($c in $ComputerName) {
Invoke-Command -ComputerName $c -Credential $cred -ArgumentList $cred,$UNCexepath {
Start-Process -Filepath $UNCexepath -Credential $cred -Verb RunAs
}
}}
You need to declare the parameters inside the Invoke-Command scriptblock:
foreach ($c in $ComputerName) {
Invoke-Command -ComputerName $c -Credential $cred -ArgumentList $cred,$UNCexepath {
param($cred,$UNCexepath)
Start-Process -Filepath $UNCexepath -Credential $cred -Verb RunAs
}
}}

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

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.

powershell - Invoke-Command : The value of the FilePath parameter must be a Windows PowerShell script file

I have a re-usable script that I've been using with success calling a remote ps1 file but now I'm trying to call a remote batch file and I get the following error message -
Invoke-Command : The value of the FilePath parameter must be a Windows
PowerShell script file. Enter the path to a file with a .ps1 file name
extension and try the command again.
This is the script -
#Admin Account
$AdminUser = "domain\svc_account"
$Password = Get-Content D:\scripts\pass\crd-appacct.txt | convertto-securestring
$Credential = new-object -typename System.Management.Automation.PSCredential -argumentlist $AdminUser, $Password
$FileName = "runme.bat"
$ItemLocation = "D:\path\to\bat\"
#Invoke Script Remotely
Invoke-Command -ComputerName Servername -filepath "$ItemLocation$FileName" -Authentication CredSSP -Credential $Credential
You should use -ScriptBlock parameter instead of -FilePath:
Invoke-Command -ComputerName Servername -ScriptBlock {& "$using:ItemLocation$using:FileName"} -Authentication CredSSP -Credential $Credential
Or if you are using PowerShell v2, which does not have $using:VariableName syntax:
Invoke-Command -ComputerName Servername -ScriptBlock {param($ItemLocation,$FileName) & "$ItemLocation$FileName"} -ArgumentList $ItemLocation,$FileName -Authentication CredSSP -Credential $Credential