Powershell: How to pass parameter with invoke-command and -filepath remotely? - powershell

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.

Related

Using Parameters when Calling Script with Start-Job

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.

Passing parameters between Powershell scripts

I simply want to be able to pass one parameter from one PS script to another, currently my script (script1) is as follows (all thanks to user CB):
$filepath = Resolve-Path "script2.ps1"
start-process -FilePath powershell.exe -ArgumentList "-file `"$($filepath.path)`""
This succesfully opens another script in via another powershell instance. Now i want to be able to carry across a parameter to the 'script2.ps1' script. I have tried the following but this doesnt not work:
script1.ps1
$name = read-host "The name"
$filepath = Resolve-Path "script2.ps1"
start-process -FilePath powershell.exe -ArgumentList "-file `"$($filepath.path)`"-name $name"
script2.ps1
Param(
[string]$name
)
write-host $name
This should simply pass over $name from script1 into $name in script2. I think im close but not quite close enough!
Thanks for any help!
The only problem I see is that you are missing a space after the last escaped ", try this:
start-process -FilePath powershell.exe -ArgumentList "-file `"$($filepath.path)`" -name $name"
Is there a specific reason why you want to run the second script in a separate instance of Powershell? If not, you would do much better just to run the script directly:
$name = read-host "The name"
.\script2.ps1 -name $name
This way you don't have to worry about escaping any of the parameters.
The way you were doing it forces all of the parameters to be converted to strings and processed by Windows command line processing. That can be a nightmare to ensure values get through in a usable form. If instead you just invoke the script directly you can pass objects as parameters and Powershell is all about using objects rather than strings.

Call another powershell pass parameter use different creds

I want to call another secondary powershell script from within my primary powershell script. I want to pass it a parameter from the primary script, the secondary script needs the username parameter, I want to pass to it, from the primary, and then have the secondary script Im calling use different credentials. I think I might be able to use invoke-command, I just dont know all the syntax, anyone able to post some examples of what I want to accomplish, and then I'll fill in the blanks if need be?
Thanks in advance! :-)
Assume that your secondary script looks like this:
param (
[string] $Username = $args[0]
)
Write-Output -InputObject $Username;
You can use the Start-Process cmdlet to launch the script with alternate credentials.
$Credential = Get-Credential;
Start-Process -Wait -NoNewWindow -FilePath powershell.exe -ArgumentList '"c:\path\to my\file.ps1" -Username "UsernameGoesHere!"' -Credential $Credential;
Or you can use the Invoke-Command cmdlet:
Invoke-Command -FilePath 'c:\path\to my\script.ps1' -Credential $Credential -ArgumentList "UsernameGoesHere!";
I got it, thanks to Trevor Sullivan for pointing me in the right direction.
I ended up just putting my second ps1 file into a scriptblock, and running it as a job, and passing it the arguments from the main script, like this
$job = Start-Job -scriptblock {
param ($username)
some code to run against the variable that was passed in
} -Args $target -credential $Cred
$target being the variable I want to pass to my scriptblock
$username being the parameter that the scriptblock accepts
Thanks.

Powershell Invoke-Command with Variable for Script Name

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.

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