Powershell Invoke-Command with Variable for Script Name - powershell

I need to execute a Powershell script on a remote machine from a local script. Problem is, I don't know the path or filename of the remote script until runitime.
I've tried the following line in my local script:
Invoke-Command -ComputerName $TargetServer -ScriptBlock { & ($TargetMSI) '$MSI' 'C:\Program Files (x86)\Vasanta.Int.MIS' 'Dev' }
Problem is this returns the error: The expression after '&' in a pipeline element produced an invalid object.
If replace the $TargetMSI with a hard-coded string literal then it works fine.
Can anyone please tell me what I need to change?

When you Invoke-Command in v2 there is no direct way to pass variables to scriptblock. You need to use -ArgumentList + param () in scriptblock combo:
Invoke-Command -ScriptBlock { param ($TargetMSI, $MSI) & $TargetMSI '$MSI' } -ArgumentList $TargetMSI, $MSI
this is fixed/ improved in v3 with $using:localvariable syntax.

Related

Unable to run the parametrized batch file on remote machine using PowerShell

Execute the remote server parametrized batch file from PowerShell.
Doesn't throw an error nor executed command on remote machine.
$path = "D:\run\test-5.2.bat";
Invoke-Command -ComputerName testserver -Scriptblock { "$path" }
Script inside the bat file is msiexec with parameters, which shall execute through Command Prompt only.
Based on this msdn link, you can run a ps1 script file on remote computers. So if it is possible to "port" the content of the bat file in a ps1 it should work. Here is the msdn example:
Example 11: Run a script on all the computers listed in a text file
PS C:\> Invoke-Command -ComputerName (Get-Content Servers.txt) -FilePath C:\Scripts\Sample.ps1 -ArgumentList Process, Service
This example uses the Invoke-Command cmdlet to run the Sample.ps1 script on all of the computers listed in the Servers.txt file. The command uses the FilePath parameter to specify the script file. This command lets you run the script on the remote computers, even if the script file is not accessible to the remote computers.
When you submit the command, the content of the Sample.ps1 file is copied into a script block and the script block is run on each of the remote computers. This procedure is equivalent to using the ScriptBlock parameter to submit the contents of the script.
Hope that helps
$path is a string. PowerShell simply echoes bare strings instead of executing them, unlike CMD or bash. Use the call operator (&):
& "$path"
or Start-Process:
Start-Process cmd.exe -ArgumentList '/c', $path -NoNewWindow -Wait
to have PowerShell execute a string as a command. Since you say you're running msiexec.exe from the batch script using the latter may be required.
On top of that you have a scope issue. The variable $path inside the scriptblock is not the same as the one in the global scope. You can mitigate that via the using: scope qualifier:
Invoke-Command -Computer testserver -Scriptblock { & "$using:path" }
or by passing $path as an argument to the scriptblock:
Invoke-Command -Computer testserver -Scriptblock { & "$($args[0])" } -ArgumentList $path

Powershell running a command from variable

I am trying to run a command that I have stored as a string in a variable, however when I try to run it with "Invoke-Command" I am told it needs to be "ScriptBlock" and not a string.
The command is:
ASIMPORT.EXE -rexactdb-01 -DTEST001 -u -~ I -URL X:\test.xml -Tglentries -OPT18 –Oauto
I am trying to run it as:
Invoke-Command -ScriptBlock $command
Tried with and without "ScriptBlock", always get the same error. Googling it, I honestly do not understand how should I approach the solution, so any advice is appreciated.
Instead of Invoke-Command, you need Invoke-Expression:
$command = 'svn help patch'
Invoke-expression $command
See cmdlet description:
The Invoke-Expression cmdlet evaluates or runs a specified string as a
command and returns the results of the expression or command. Without
Invoke-Expression, a string submitted at the command line would be
returned (echoed) unchanged.
Define your variable as a scriptblock.
Like that:
$ScriptBlock = [ScriptBlock]::Create("get-process")
Invoke-Command -ScriptBlock $ScriptBlock
Try Below
Invoke-Command -ScriptBlock {&$command}

PowerShell execute Sqlpackage.exe remotely [duplicate]

I'm tearing my hair out trying to invoke-command but pass the path to the exe as a parameter
eg:
I want to take this command
powershell Invoke-Command -ComputerName localhost -ScriptBlock { param($command ) C:\windows\system32\getmac.exe /$command } -ArgumentList ?
and translate it into a form like this
powershell Invoke-Command -ComputerName localhost -ScriptBlock { param($path, $command ) $path\getmac.exe /$command } -ArgumentList C:\windows\system32,?
I've tried all manner of quoting, ampersands and other contortions but can't get it to work. The above attempt results in
Unexpected token '\getmac.exe' in expression or statement.
At line:1 char:97
(I don't really want to invoke getmac on localhost, this is the runnable, SO distilled version)
Try this option. It shows me help for cscript.exe.
C:\>powershell.exe Invoke-Command -ComputerName localhost -ScriptBlock { param($path, $command ) cmd /c $path $command } -args '"C:\windows\system32\cscript.exe"','"/?"'
I tried other options using & and then path and arguments and it was giving me missing } exception. Then using cmd /c instead of & inside scriptblock fixed the issue.
Powershell won't parse a string as a command that way. For e.g. if you do this:
$path="C:\Windows\System32"
$path\getmac.exe
You would get the same error. The trick to work around this is to use the invoke operator &:
&$path\getmac.exe
or in your example, like this (also note that for a command that you pass to the powershell executable, you must wrap it in scriptblock braces):
powershell -command {Invoke-Command -ComputerName localhost -ScriptBlock { param($path, $command ) &$path\getmac.exe /$command } -ArgumentList C:\windows\system32,?}

PowerShell function with parameters? [duplicate]

This question already has an answer here:
Parameter interpretation when running jobs
(1 answer)
Closed 6 years ago.
I have a PoSH script that I can't figure out is not running..
function Connect-AD
{
Param($mod,$cmd)
Write-Host "$mod $cmd"
Write-Host "`tConnecting to AD: $DC`n"
$ADSession = New-PSsession -ComputerName $DC -Credential $MyCredential
Invoke-Command -Command {Import-Module ('$mod') -Cmdlet ('$cmd')} -Session $ADSession
Import-PSSession -Session $ADSession -Module ('$mod') -Prefix r | Out-Null
}
I then try to call this with..
Connect-AD -mod 'ActiveDirectory' -cmd 'Get-ADUser,New-ADUser'
But no mater what I do I keep getting..
The specified module '$mod' was not loaded because no valid module file was found in any module directory.
The Write-Host inside the function outputs the parameters correctly, so it is getting that far. However it is not being passed into the Invoke-Command or Import-PSSession?
I've tried different ways to escape the parameters, etc.. but no luck.
What am I not doing correctly? Anyone able to help me out? Thanks.
Single quoted strings don't interpolate variables, '$mod' is a literal string "dollar m o d".
And you probably need to read all the similar questions on passing parameters to Invoke-Command, because the command {} is running on another computer - how will it know what the variable $mod is on your computer?
Passing string $variable to invoke-command scriptblock parameter -name
Powershell: How to pass parameter with invoke-command and -filepath remotely?
Something like
Invoke-Command -Command {param($mod, $cmd) Import-Module $mod -Cmdlet $cmd} -Session $ADSession -ArgumentList $mod,$cmd
Help Links (if available):
Invoke-Command
Import-Module

Trouble Executing a .cmd file during a PS-Session

Im trying to execute a .bat file remotely in a powershell script. The code in my script file looks something like this:
$server
$cred
# Both of these methods are strings pointing to the location of the scripts on the
# remote server ie. C:\Scripts\remoteMethod.cmd
$method1
$method2
$scriptArg
Enter-PSSession $server -Credential $cred
Invoke-Command {&$method1}
if($?)
{
Invoke-Command {&$method2 $args} -ArgumentList $scriptArg
}
Exit-PSSession
But whenever I run it I get
The term 'C:\Scripts\remoteMethod.cmd' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
This happens even if i switch around the order the methods are called in.
I found this question Using Powershell's Invoke-Command to call a batch file with arguments and have tried the accepted answers to no avail.
I wouldn't have expected the $method1 and $method2 variables to be available inside the scriptblock for Invoke-Command. Usually you would have to pass those in via the -ArgumentList parameter e.g.:
Invoke-Command {param($method, $arg) &$method $arg} -Arg $method2 $scriptArg
But it seems in your case the path to the CMD file is making it across the remote connection. Try this to see if the problem is related to a modified ComSpec environment variable on the remote machine:
Invoke-Command {param($method, $arg) cmd.exe /c $method $arg} -Arg $method2, $scriptArg