I'm looking to install the Citrix VDA remotely. I ran this same command on the app server and it installed like I would expect. But now when I try to install it remotely with the invoke-command I get an error.
Invoke-Command -computer appserver.domain.com -scriptblock {start-process -FilePath "C:\XenDesktop 7.15\x64\XenDesktop Setup\XenDesktopVDASetup.exe" -ArgumentList "/noreboot /quiet /components VDA,plugins /masterimage /baseimage /enable_remote_assistance /enable_hdx_ports /optimize /controllers "ddc.domain.com""}
A positional parameter cannot be found that accepts argument 'ddc.domain.com'.
+ CategoryInfo : InvalidArgument: (:) [Start-Process], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.StartProcessCommand
+ PSComputerName : appserver.domain.com
You should either put dcc.domain.com in single quotes: 'ddc.domain.com' or fix those double quotes. To use double quotes in a double quoted string, you'll need to double them up:
-ArgumentList "/noreboot /quiet /components VDA,plugins /masterimage /baseimage /enable_remote_assistance /enable_hdx_ports /optimize /controllers ""ddc.domain.com"""
-ArgumentList '/noreboot /quiet /components VDA,plugins /masterimage /baseimage /enable_remote_assistance /enable_hdx_ports /optimize /controllers "ddc.domain.com"'
Related
How to use -ArgumentList with Invoke-Command to pass flags to a script?
# File: ./setup.ps1
param(
[Parameter(Mandatory=$false)]
[alias("force")]
[switch]$opt_force
)
if ($opt_force) {
write-host "FORCING something!"
}
write-host "Done"
Powershell Command Line:
PS> Invoke-Command -Computer pv3039 -FilePath ./setup.ps1 -ArgumentList "-force"
Error Message:
positional parameter cannot be found that accepts argument '-force'.
+ CategoryInfo : InvalidArgument: (:) [], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound
+ PSComputerName : pv3039
If you want to call a remote script, you can use Start-Process instead of Invoke-Command. Maybe you can try something like this.
Start-Process PowerShell -ArgumentList "YOUR_SCRIPT_PATH\setup.ps1 -Force" -NoNewWindow -Wait
This way it can accept parameters from the called script.
I tried different ways to escape the space in "Program Files" but this is not working. I receive the following error in Jenkins after this part is executed:
powershell.exe : FileStream was asked to open a device that was not a file. For support for devices like 'com1:' or 'lpt1:', call At
C:\web\JenkinsMaster\workspace\XXX#tmp\durable-d3011838\powershellWrapper.ps1:5
char:3
+ & powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -Fi ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (FileStream was ... 'lpt1:', call :String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError CreateFile, then use the FileStream constructors that take an OS handle as an IntPtr.
CategoryInfo : OpenError: (:) [Out-File], NotSupportedException
FullyQualifiedErrorId : FileOpenFailure,Microsoft.PowerShell.Commands.OutFileCommand
PSComputerName : XXXXX
powershell script: '''
$pass = ConvertTo-SecureString -AsPlainText "XXXX" -Force
$cred = New-Object System.Management.Automation.PSCredential -ArgumentList "XXXX",$pass
$sessionOption = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck
$session = New-PSSession -ComputerName XXXXXXXX -UseSSL -Credential $cred -SessionOption $sessionOption
Copy-Item $env:WORKSPACE\\* -Destination "C:\\data\\install\\" -Filter *TEST* -Recurse -Force -Verbose -ToSession $session
$filename = $env:JOB_NAME + "_" + $env:BUILD_DISPLAY_NAME + "_wwwroot.7z"
Invoke-Command -Session $session -ScriptBlock {cmd /c "C:\\Program Files\\7-Zip\\7z.exe\\" x C:\\Data\\Install\\$filename -oC:\\data\\install\\test -aoa >NUL}
Remove-PSSession $session
Exit-PSSession
'''
If I change the Invoke-Command to the following, the Program Files directory seems to be resolved correctly, but then the variable $filename is not resolved anymore.
Invoke-Command -Session $session -ScriptBlock {cmd /c \'"C:\\Program Files\\7-Zip\\7z.exe" x C:\\Data\\Install\\$filename -oC:\\data\\install\\test -aoa >NUL'}
powershell.exe : NotSpecified: (:String) [], RemoteException At
C:\web\Jenkins\workspace\XXX#tmp\durable-53dbead2\powershellWrapper.ps1:5
char:3
+ & powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -Fi ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (NotSpecified: (...RemoteException:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
CategoryInfo : NotSpecified: (:String) [], RemoteException
FullyQualifiedErrorId : NativeCommandError
PSComputerName : XXXXX
ERROR: The system cannot find the file specified.
C:\Data\Install\$filename
System ERROR:
The system cannot find the file specified.
Hopefully you can assist me in this case! The rest of the commands is working fine.
Thanks!
The 7z.exe path in your first command has an extraneous trailing \, which causes problems:
cmd /c "C:\\Program Files\\7-Zip\\7z.exe\\" # <- trailing \\ shouldn't be there
In your 2nd command, you're using single quotes around the command passed to cmd /c ('...'), but the contents of '...' strings in PowerShell are treated as literals, which explains why $fileName was not expanded (interpolated);
only double-quoted ("...") strings and, within limits, unquoted command arguments are expanded in PowerShell; e.g., compare the output from Write-Output '$HOME' to the output from Write-Output "$HOME" / Write-Output $HOME.
As iRon mentions, there's no need to involve cmd at all - PowerShell is perfectly capable of executing command-line programs directly, so this should work:
Invoke-Command -Session $session -ScriptBlock { & "C:\\Program Files\\7-Zip\\7z.exe" x C:\\Data\\Install\\$using:filename -oC:\\data\\install\\test -aoa >$null }
Due to invoking 7z.exe directly, now there's no outer quoting needed anymore, and $fileName should be expanded.
Note, however, that $fileName was replaced with $using:fileName, which is necessary in order for the target session to know about the local $fileName variable - see Get-Help about_Remote_Variables.
Since the 7z.exe file path is quoted (of necessity, due to containing spaces), you must use &, the call operator, to invoke it.
Since the > redirection is now performed by PowerShell itself, the cmd-style >NUL output suppression was replaced with its PowerShell analog, >$null.
I wonder if it necessarily at all to invoke a CMD shell for this.
I guess it would be simpler to directly invoke the 7z.exe with its parameters.
Nevertheless, you can build you own script block like this:
[ScriptBlock]::Create('cmd /c "C:\\Program Files\\7-Zip\\7z.exe" x C:\\Data\\Install\\' + $filename + ' -oC:\\data\\install\\test -aoa >NUL')
I am a student and am very new to PowerShell.
I am trying to get my msi to download remotely but i keep encountering an error.
A positional parameter cannot be found that accepts argument '\\share\folder\Path to msi'.
+ CategoryInfo : InvalidArgument: (:) [Start-Process], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.StartProcessCommand
+ PSComputerName : RemoteDesktopName
Here is my script:
$msi = #(\\share\folder\Path to msi)
Invoke-Command -ComputerName PCname -ScriptBlock {param($msi) Start-Process msiexec.exe /i "\\Path to msi" /qn /passive -Wait
Start-Sleep 5 } -ArgumentList $msi
Could anyone please help me? Any feedback will be greatly appreciated.
You dont have to make $msi an array if the only thing you parse is a string of the Path. Also, why would you use "\Path to msi" inside the Invoke-Command if you parse $msi?
Edit: You should probaly parse the arguments to the msiexec.exe via -Argumentlist.
Try this:
$msi = "Path to msi"
Invoke-Command -ComputerName PCname -ScriptBlock {param($msi) Start-Process msiexec.exe -Wait -ArgumentList "/I $msi /qn /passive"} -ArgumentList $msi
I have the below PowerShell code:
$HOME_DIR=[Environment]::GetEnvironmentVariable("HOME")
$WORKING_PATH="C:\tests\automation"
$TOOLS_PATH="$WORKING_PATH\Tools"
Start-Process -FilePath "$HOME_DIR\perl\perl.bat" "$TOOLS_PATH\my_perl_script.pl" -ArgumentList 'arg1' 'arg2' -NoNewWindow
I'm getting error:
Start-Process : A positional parameter cannot be found that accepts argument 'C:\tests\automation\Tools\my_perl_script.pl'.
At C:\RunUIAutomaionTests.ps1:46 char:14
+ Start-Process <<<< -FilePath "$HOME_DIR\perl\perl.bat" "$TOOLS_PATH\my_perl_script.pl"
-ArgumentList 'arg1' 'arg2' -NoNewWindow
+ CategoryInfo : InvalidArgument: (:) [Start-Process], ParameterBindingException
+ FullyQualifiedErrorId :<br> PositionalParameterNotFound,Microsoft.PowerShell.Commands.StartProcessCommand
What I'm missing?How should I execute my_perl_script.pl using perl.bat with the arguments 'arg1' and 'arg2'?
Why so complicated?
You can call perl doirectly like that:
...
$TOOLS_PATH="$WORKING_PATH\Tools"
...
perl $TOOLS_PATH\my_perl_script.pl arg1 arg2
Just make sure perl executable is in Windows path
I am unable to run an invoke-command script to install printers on a remote machine. My code works locally, but as soon as I pipe it into Invoke-command, i get errors.
Local:
$Printer = "\\server1\printer1"
(New-Object -Com Wscript.Network).AddWindowsPrinterConnection($Printer)
And this adds the printer just fine. I can do this same command on the remote computer with no issues. But when i tried to execute the command remotely I have the issues.
Remote:
$compname = "computer"
$Printer = "\\server1\printer1"
Invoke-Command -ComputerName $CompName -Scriptblock {(New-Object -Com Wscript.Network).AddWindowsPrinterConnection('$Printer')}
Which returns the error "The printer name is invalid"
So I tried to see what the shell was sending to the remote computer with the following code, and everything in the write output looks good, but I still get errors:
Invoke-Command -ComputerName $CompName -Scriptblock {(New-Object -Com Wscript.Network).AddWindowsPrinterConnection('$Printer'); write-host "(New-Object -Com Wscript.Network).AddWindowsPrinterConnection('$Printer')"}
Output:
Exception calling "AddWindowsPrinterConnection" with "1" argument(s): "The printer name is invalid. (Exception from
HRESULT: 0x80070709)"
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ComMethodTargetInvocation
+ PSComputerName : computer
(New-Object -Com Wscript.Network).AddWindowsPrinterConnection('\\server1\printer1')
Edit 1/5/2015
So I've tried Paul's code with a number of different entries to the argumentlist. All have not worked so far. i think the first 3 are closer to an answer.
-ArgumentList ""\\server1\printer1""
-ArgumentList ""'\\server1\printer1'""
-ArgumentList "\"\\server1\printer1""
Results in:
Invoke-Command : A positional parameter cannot be found that accepts argument '\\server1\printer1'.
At line:1 char:1
+ Invoke-Command -ComputerName $CompName -Scriptblock {(New-Object -Com Wscript.Ne ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Invoke-Command], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.InvokeCommandCommand
-ArgumentList "'\\server1\printer1'"
-ArgumentList \'"\\server1\printer1"'
-ArgumentList \""\\server1\printer1""
-ArgumentList \"\\server1\printer1"
Result in:
Exception calling "AddWindowsPrinterConnection" with "1" argument(s): "The printer name is invalid. (Exception from
HRESULT: 0x80070709)"
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ComMethodTargetInvocation
+ PSComputerName : sso-mxl327082y
Try this:
Invoke-Command -ComputerName $CompName -Scriptblock {(New-Object -Com Wscript.Network).AddWindowsPrinterConnection($args[0]); write-host "(New-Object -Com Wscript.Network).AddWindowsPrinterConnection($($args[0]))"} -ArgumentList "\\server1\printer1"
I think it´s because your $printer variable is placed between single quotes, variables between single quotes are not interpreted by powershell. So the printername your function probably gets is "$printer".
In case you wonder it is printed out correctly in your write-host statement because here the single quotes are inside a string.
you need to use $Using:yourvar to pass variables to the scriptblock
$compname = "computer"
$Printer = "\\server1\printer1"
Invoke-Command -ComputerName $CompName -Scriptblock
{
(New-Object -Com Wscript.Network).AddWindowsPrinterConnection($Using:$Printer)
}
I think it's because of the so called 'double hop problem', where your authentication isn't transfered to the next remote computer which is sharing the printer.
I tried to solve similar problem using add-printer and following this article double hop problem solution.
However, although it works with get-childitem etc. it doesn't work with add-printer cmdlet.