Run Executable from Powershell script with parameters - powershell

So I have a powershell script that is supposed to run an executable with an argument to pass to set which method I want to run, and I need to pass a parameter, which is a directory to a config file. So this is what I have
Start-Process -FilePath "C:\Program Files\MSBuild\test.exe" -ArgumentList /genmsi/f $MySourceDirectory\src\Deployment\Installations.xml
/f is the shortname and file is the long name for my attribute... I get an error in powershell telling me that a positional parameter cannot be found for /f or /file.
Any thoughts?

Try quoting the argument list:
Start-Process -FilePath "C:\Program Files\MSBuild\test.exe" -ArgumentList "/genmsi/f $MySourceDirectory\src\Deployment\Installations.xml"
You can also provide the argument list as an array (comma separated args) but using a string is usually easier.

Here is an alternative method for doing multiple args. I use it when the arguments are too long for a one liner.
$app = 'C:\Program Files\MSBuild\test.exe'
$arg1 = '/genmsi'
$arg2 = '/f'
$arg3 = '$MySourceDirectory\src\Deployment\Installations.xml'
& $app $arg1 $arg2 $arg3

I was able to get this to work by using the Invoke-Expression cmdlet.
Invoke-Expression "& `"$scriptPath`" test -r $number -b $testNumber -f $FileVersion -a $ApplicationID"

Just adding an example that worked fine for me:
$sqldb = [string]($sqldir) + '\bin\MySQLInstanceConfig.exe'
$myarg = '-i ConnectionUsage=DSS Port=3311 ServiceName=MySQL RootPassword= ' + $rootpw
Start-Process $sqldb -ArgumentList $myarg

Related

powershell start-process doesn't accept two commands in ArgumentList because they have a same parameter

I want to launch a admin powershell with two commands :
$command1 = "Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\{example}' -Name DHCPClassId -Value National"
$command2 = "Restart-NetAdapter -Name Ethernet"
Start-Process powershell -Verb 'RunAs' -ArgumentList "-NoExit","-Command &{$command1,$command2}"
And i have an error : he don't want to execute these two because they have a same parameter (-Name), so, what can i do ?
PowerShell's statement separator is ;, not , (the latter constructs arrays).
Also:
Even though passing arguments individually, as elements of an array to Start-Process is conceptually clean, it should be avoided due to a long-standing bug: pass a single string encoding all arguments to -ArgumentList - see this answer for more information.
When using PowerShell's CLI, -Command & { ... } is never necessary - just use -Command ...; that is, there is no reason to construct a script block ({ ... }) that you must then invoke with & - all commands given are directly executed by default.
To put it all together:
$command1 = "Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\{example}' -Name DHCPClassId -Value National"
$command2 = "Restart-NetAdapter -Name Ethernet"
Start-Process powershell -Verb RunAs "-NoExit -Command $command1; $command2"

Powershell Start-Process with Splatting

I want to call a "PS App Deployment Toolkit"-package (Link) from a PowerShell-Script with arguments.
The mentioned "PS App Deployment Toolkit"-package is a powershell-script, which I want to call with parameters. (Call a .ps1 from a .ps1)
I want to use splatting for the parameters.
I want to wait for the script to end.
I want to get the exit-code from the script.
Here is my code, which is not working:
$PSADToolKitInstallWrapper = "C:\Temp\MyPackage\PS-AppDeploy.ps1"
$PSADToolKitParameters = #{
"DeploymentType" = "Uninstall";
"DeployMode" = "Interactive";
"AllowRebootPassThru" = $True;
"TerminalServerMode" = $False;
"DisableLogging" = $False;
}
$InstallStatus = Start-Process -FilePath "PowerShell.exe" -ArgumentList $PSADToolKitInstallWrapper #PSADToolKitParameters -Wait -PassThru
Write-Host "Exit-Code: $( $InstallStatus.ExitCode )"
This Line would work fine, but I want to set the Parameters like in the example above:
$InstallStatus = Start-Process -FilePath "PowerShell.exe" -ArgumentList "$PSADToolKitInstallWrapper","-DeploymentType Install -DeployMode Silent -AllowRebootPassThru -TerminalServerMode" -Wait -PassThru
Could you please assist me to get this working?
Thank you!
I don't think you need to try so hard. Why run powershell.exe from inside a PowerShell script? You're already running PowerShell. Just run the command line you want:
$PSADToolKitParameters = #{
"DeploymentType" = "Uninstall"
"DeployMode" = "Interactive"
"AllowRebootPassThru" = $True
"TerminalServerMode" = $False
"DisableLogging" = $False
}
C:\Temp\MyPackage\PS-AppDeploy.ps1 #PSADToolKitParameters
If the path and/or filename to the script you want to run contains spaces, then call it with the invocation operator (&) and quote the filename; example:
& "C:\Temp\My Package\PS-AppDeploy.ps1" #PSADToolKitParameters
Checking the results of the script depends on what the script returns. If it returns an output object, then you can simply assign it:
$output = C:\Temp\MyPackage\PS-AppDeploy.ps1 ...
If the script runs an executable that sets an exit code, you check the value of the $LASTEXITCODE variable (this is analogous to the %ERRORLEVEL% dynamic variable in cmd.exe).

Run batch file on UNC path with parameters and capture output to variable without Community Extensions

I'd like to run a command such as:
pushd \\myServer\share\scripts
myBatchFile.bat param1 param2 "parameter 3"
popd
Only initiating through powershell.
NB: The name of the batch file is held in a variable, as are each of the parameters.
function Escape-StringForCmd($a)
{
if(($a -like '*"*') -or ($a -like '* *'))
{
('"{0}"' -f ($a -replace '"','""'))
}
else
{
$a
}
}
$batch = "myBatchFile.bat"
$p1 = "param1"
$p2 = "param2"
$p3 = "parameter 3"
$batch = Escape-StringForCmd($batch)
$p1 = Escape-StringForCmd($p1)
$p2 = Escape-StringForCmd($p2)
$p3 = Escape-StringForCmd($p3)
pushd \\myServer\share\scripts
cmd.exe /c $batch $p1 $p2 $p3
#above fails; no error returned; I think because cmd doesn't like the UNC path, so reverts to the system directory
Start-Process "cmd.exe" -ArgumentList "/c",$batch,$p1,$p2,$p3 -NoNewWindow -Wait -WorkingDirectory "\\myServer\share\scripts"
#above also fails; not sure why as looks healthy when running outside of ps1 file
popd
I've also interested in capturing the output - though as at present the batch file's not being run I'll focus on that initially.
I've not yet tried the ProcessStartInfo solution (see link below) as it seems start-process, or simply cmd.exe /c should work (certainly when I've run tests outside of a ps1 file this has worked), but I'll resort to trying that method shortly.
ProcessStartInfo solution: Powershell: Capturing standard out and error with Process object
Using #JNK's answer along with the below hack, I found a way to get this to work
$tempBatchName = ".\~myTempBatchFile.bat" #put this in a variable so we can easily amend if required
"
pushd \\myServer\share\scripts
$batch $p1 $p2 $p3
popd
" | out-file $tempBatchName -encoding ascii
$MyCmd = ("{0} *>&1" -f $tempBatchName)
$ReturnOutput = Invoke-Expression $MyCmd
$ReturnOutput | out-file ("{0}.log" -f $tempBatchName)
remove-item $tempBatchName
Is there a reason you can't use invoke-expression for this?
$MyCmd = "$batch $p1 $p2 $p3 *>&1"
$ReturnOutput = Invoke-Expression $MyCmd
The *>&1 puts all output from the StdErr and StdOut to the output stream.
More info on redirection operators here.

Call PowerShell script with arguments from another powershell script

How do you call a PowerShell script which takes named arguments from within a PowerShell script?
foo.ps1:
param(
[Parameter(Mandatory=$true)][String]$a='',
[Parameter(Mandatory=$true)][ValidateSet(0,1)][int]$b,
[Parameter(Mandatory=$false)][String]$c=''
)
#stuff done with params here
bar.ps1
#some processing
$ScriptPath = Split-Path $MyInvocation.InvocationName
$args = "-a 'arg1' -b 2"
$cmd = "$ScriptPath\foo.ps1"
Invoke-Expression $cmd $args
Error:
Invoke-Expression : A positional parameter cannot be found that accepts
argument '-a MSFT_VirtualDisk (ObjectId =
"{1}\\YELLOWSERVER8\root/Microsoft/Windo...).FriendlyName -b 2'
This is my latest attempt - I've tried multiple methods from googling none seem to work.
If I run foo.ps1 from the shell terminal as ./foo.ps1 -a 'arg1' -b 2 it works as expected.
After posting the question I stumbled upon the answer. For completeness here it is:
bar.ps1:
#some processing
$ScriptPath = Split-Path $MyInvocation.InvocationName
$args = #()
$args += ("-a", "arg1")
$args += ("-b", 2)
$cmd = "$ScriptPath\foo.ps1"
Invoke-Expression "$cmd $args"
Here is something that might help future readers:
foo.ps1:
param ($Arg1, $Arg2)
Make sure to place the "param" code at the top before any executable code.
bar.ps1:
& "path to foo\foo.ps1" -Arg1 "ValueA" -Arg2 "ValueB"
That's it !

How to pass Multiple Variables as Arguments to a Script using Start-job

How to pass Multiple Variables as Arguments to a Script using Start-job.
Start-Job -Name "$jobName" -filepath $TestTool -ArgumentList $compare1
how to retrieve this argument values (of $arg1 and $arg2) in a script TestTool.ps1?
Rgds
Naveen
PS>Start-Job -Name test -ArgumentList #("hello","word") -FilePath \\server\share\test.ps1
in test.ps1 just echo the $args var
$args
result :
PS>Receive-Job test -keep
hello
word
http://technet.microsoft.com/en-us/library/hh849698.aspx
"Because all of the values that follow the ArgumentList parameter name are interpreted as being values of ArgumentList, the ArgumentList parameter should be the last parameter in the command."
So I guess tha something like:
... -ArgumentList $arg1 $arg2
should work?