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}
Related
I recently started to learn Powershell. My problem is that I'm trying to run a powershell script to unfreeze a remote machine, but one of the parameters of Time Freeze contains a dollar sign. How do I do that?
Basically what I need to do is to run the following command:
cmd.exe /c "C:\Program Files\Toolwiz Time Freeze 2017\ToolwizTimeFreeze.exe" /unfreeze /usepass=$password
Where the dollar sign is part of the password.
If I run it on the powershell console directly on the remote machine, it works (I just have to add single quotes around $password). But when I try to run the script from my local machine, it gets stuck on it and I have to Ctrl C to cancel it.
The script in question is this:
$User = "user"
$PWord = ConvertTo-SecureString "password" -AsPlainText -Force
$Ip = Read-Host -Prompt 'Insira o IP da maquina de destino:'
$Cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, $PWord
$sess = New-PSSession -Credential $Cred -ComputerName $Ip
Enter-PSSession $sess
Invoke-Command -ComputerName $Ip -ScriptBlock { cmd.exe /c "C:\Program Files\Toolwiz Time Freeze 2017\ToolwizTimeFreeze.exe" /unfreeze /usepass=$password} -Credential $Cred
Remove-PSSession $sess
Exit-PSSession
I tried using Start-Process -Filepath and & to run the Time Freeze but it doesn't work neither (the script is executed but nothing happens at all), but when I try to run other commands like creating a new folder on the remote machine or restarting it, it works perfectly.
I don't know what else to try.
Edit1: I tried to pass the parameter with the single quotes and I also
tried using -argumentlist, but it doesn't work neither.
Edit2: If I run the script locally, it works perfectly, even on the remote machine. But when I try to run it remotely it doesn't work. It seems very strange to me because I can run other commands remotely succesfully, but with this one I'm having troubles.
Edit3: I forgot to update the question here, but I solved it. The problem wasn't about the password after all. I discovered by chance that in my script I had to stop the TimeFreeze proccess before I could call it again, otherwise I'd got stuck on it. So that's how I solved it.
Have you tried escaping the $ in the password?:
/usepass="`$password"
No idea if this works, if not you could assign the password to a variable then provide that as an argument
$mypassword = "`$password"
If possible, try to wrap all of the arguments you're passing to cmd.exe up into a variable prior to calling Invoke-Command. Then you can pass the variable via -ArgumentList.
Here's a little example where i'm placing all my arguments into a $params variable and then passing it into the ScriptBllock of InvokeCommand. Note that you need to add the param() section at the top to accept your the variable you pass in via -ArgumentList.
$params = #("/c ipconfig /all")
Invoke-Command -ComputerName $Computer -Credential $Cred -ScriptBlock {
param(
$params
)
Write-Host "We passed in the following parameters: '$params'"
& "cmd.exe" $params
} -ArgumentList $params
If you are running this from PowerShell, you need to wrap quotes around values with spaces and escape the dollar sign in PowerShell and CMD.
$sb = { cmd.exe /c """C:\Program Files\Toolwiz Time Freeze 2017\ToolwizTimeFreeze.exe"" /unfreeze /usepass=\`$password"}
Invoke-Command -ComputerName $Ip -ScriptBlock $sb -Credential $Cred
I am working on a script that must change users in the middle of running in order to be able to access a network folder. I have figured out how to get the credentials working, but now cannot understand how to pass parameters to the second script that is being called. The code that I currently have:
$myJob = Start-Job -ScriptBlock {& "\\my\folder\path\script.ps1" -serverName $serverName -serverInstance $serverInstance} -Credential $cred
$myJob | Wait-Job
$myJob | Receive-Job -Keep
I need to pass the serverName and serverInstance variables to the script that Start-Job is running, while also still being able to use credential. Is there a way to do this?
I have investigated Invoke-Command and Invoke-Expression, but neither of those fit this situation. Invoke-Command doesn't work with remote computers/drives and Invoke-Expression doesn't work with credentials. I tried the answer that was provided here, but that would not correctly pass in the parameters either.
Any help is much appreciated as I have been working on this problem for a few hours now. I am sure I am missing something obvious.
You can use the using scope modifier provided you are on PowerShell version 3 or higher:
$myJob = Start-Job -ScriptBlock {& "\\my\folder\path\script.ps1" -serverName $using:serverName -serverInstance $using:serverInstance}
You can also use local variables in remote commands, but you must indicate that the variable is defined in the local session. Beginning in Windows PowerShell 3.0, you can use the Using scope modifier to identify a local variable in a remote command. The syntax of Using is as follows:
$Using:<VariableName>
If you are on PowerShell version 2, you will need to utilize the -ArgumentList parameter and then modify your scriptblock to accept the arguments that are passed. Avshalom comments on one way to do this.
See About_Remote_Variables for more information.
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,?}
so there's a lot of similar topics to this I've found, but I can't find anything that correlates with my issue.
invoke-command -computername $serverLocation -Credential $cred -filepath "C:\path\script2.ps1" -ArgumentList $configPath
I am calling a for a script that is stored on my local machine to run on another server. Everything works as intended except for passing the "configPath" variable. This is how I initiate the script -
. .\script1.ps1 -serverLocation 'serverNameHere' -username 'userNameHere' -configPath 'configPathHere'
It correctly grabs all the other parameters I pass into the first script. It just won't pass the configPath to the second script in the 'filepath'.
How can I get this parameter to pass through? Thanks so much.
In script2.ps1, you should define a param() block that accepts the parameter, and then you can refer to it by whatever name you give it. If you don't want to use a param() block then using $args[0] should work.
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.