I have a script in which I need to run one command as an administrator. When I ran this command the script errors with a 1734 error.
My script is very basic:
runas /user:Administrator "myexec.exe \"param with spaces\" otherparam -Djava.ext.dirs=%JAVA_EXT_DIRS%"
The problem comes from the variable JAVA_EXT_DIRS which is kind of huge.
This is an old question, but I've ran into the same problem on Windows 10 with the runas command now. It turns out there's a maximum length for the program parameter, which has to be below 995 characters.
For example, this command still works:
runas /user:someuser /savecreds "cmd.exe 1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"
The program parameter here has 994 characters, and it should open a new command prompt. But if you add one more 1 within that parameter, the execution will fail with a 1734: The array bounds are invalid. error.
And if you increase the the program parameter even further to 1026 characters, the error changes to -2147024809: The parameter is incorrect..
The regular limit for command line parameters seems to be much much larger (I've read something about 8191 characters here on SO), so this seems to be a problem with runas.exe itself.
Edit:
I even ran into a similar problem when I tried to use a PowerShell script with the -Credential flag like this:
$username = "username"
$password = "password"
$securePassword = ConvertTo-SecureString $password -AsPlainText -Force
$credentials = New-Object System.Management.Automation.PSCredential $username, $securePassword
$argument = $args[0]
Start-Process -FilePath "C:\path\to\my.exe" -Credential $credentials -ArgumentList "-arg $argument"
So it's probably a problem with the underlying Windows mechanics and not runas.exe itself.
The value of %JAVA_EXT_DIRS% may contain spaces too. You better put it in double quotes:
runas /user:Administrator "myexec.exe \"param with spaces\" otherparam -Djava.ext.dirs=\"%JAVA_EXT_DIRS%\""
Related
$secpasswd = ConvertTo-SecureString "Password" -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential("administrator", $secpasswd)
$Path = "$env:userprofile\AppData\Local"
cd "$Path\telegraf"
$installtelegraf = .\telegraf.exe --service install --config "$Path\telegraf\telegraf.conf"
$start_telegraf = telegraf.exe --service start
$net_telegraf = net start telegraf
Start-Process Powershell.exe -Credential $mycreds -ArgumentList $installtelegraf $start_telegraf $net_telegraf
But don't know I am getting errors. I'll use this script for automation process to install it on our clients through Group Policy.
Any kind of help will be appreciated.
Thanks.
Your intent is to define the command lines to invoke later with Start-Process as strings, and for that you must use quoting; e.g.:
# Without enclosure in '...' you would *instantly* execute the command.
$start_telegraf = 'telegraf.exe --service start'
To put it all together:
$installtelegraf = "telegraf.exe --service install --config `"$Path\telegraf\telegraf.conf`""
$start_telegraf = 'telegraf.exe --service start'
$net_telegraf = 'net start telegraf'
Start-Process Powershell.exe -Credential $mycreds -ArgumentList #"
$installtelegraf
$start_telegraf
$net_telegraf
"#
Note:
The $installtelegraf = ... assignment uses an expandable (double-quoted) string ("..."), so as to ensure that expansion (string interpolation) takes place, i.e. so that $Path is expanded (replaced with its value); the embedded " chars. must therefore be escaped as `".
Since the other assignments do not require expansion, verbatim (single-quoted) strings ('...') are used.
Note the use of an expandable here-string in the Start-Process call, to make it easy to pass the three variables as separate statements; alternatively, you could have used a single-line string with ; as the statement separator.
Note that I've removed .\ from the first telegraf.exe call, as it doesn't appear in the second.
Generally, note that the target user must have permission to access the caller's working directory. If not, a different one must be specified via -WorkingDirectory.
I'm trying to start my script from Explorer. I've found the solution and it works if script doesn't have any parameters.
$file = [System.IO.Directory]::GetCurrentDirectory() + "\Trees.ps1"
Start-Process powershell -verb runas -ArgumentList "-ExecutionPolicy UnRestricted -File `"$($file)`""
However, if I add additionall parameters just like the first it ceases to work. Ie. this code throws "The string is missing the terminator: '." error.
$file = [System.IO.Directory]::GetCurrentDirectory() + "\Trees.ps1"
$Context = [System.IO.Directory]::GetCurrentDirectory()
Start-Process powershell -verb runas -ArgumentList "-ExecutionPolicy UnRestricted -Context '"$($Context)'" -File `"$($file)`""
I'm using this way of expecting variable:
[Parameter(Mandatory=$True)]
[string]$Context,
What can I do to pass more then one variable with spaces in ArgumentList?
I suspect that I should pass arguments for file content in other way than when just passing file name, but couldn't find solution.
In addition to the back ticks issue that Theo noted, -context should follow -file.
-File
Runs the specified script in the local scope ("dot-sourced"), so that the
functions and variables that the script creates are available in the
current session. Enter the script file path and any parameters.
File must be the last parameter in the command, because all characters
typed after the File parameter name are interpreted
as the script file path followed by the script parameters.
So your command line would be
Start-Process powershell -verb runas -ArgumentList "-ExecutionPolicy UnRestricted -File `"$($file)`" -Context $($Context)"
Since you are using an external process call, you will need to use inside double quotes instead of single quotes. You can escape double quotes simply by adding another double quote ("").
Start-Process powershell -verb runas -ArgumentList "-ExecutionPolicy UnRestricted -File ""$file"" -Context ""$Context"""
Quick question. I am trying to write the following PowerShell script, but I would like it to fit on a single line:
$app = New-Object -comobject Excel.Application
$wb1 = $app.Workbooks.Open("C:\xampp\upload_files\Launchpad.xlsm")
$app.Run("Refresh")
$wb1.Close($false)
$app.Quit()
The pseudo-code would look something like this:
$app = New-Object -comobject Excel.Application AND $wb1 = $app.Workbooks.Open AND "C:\xampp\upload_files\Launchpad.xlsm") AND $app.Run("Refresh") AND $wb1.Close($false) AND $app.Quit()
The reason I want to fit on a line is because I would like to insert the arguments directly in the 'arguments' box of Windows Task Scheduler. The reason for this is that for some reason scripts have been disabled (e.g. I cannot call a .ps1 file...)
I know this will still work, as I already have a "one liner" PS script running. What would the syntax look like??
Kind regards,
G.
Powershell statements can be separated with semicolons:
$app = New-Object -COM 'Excel.Application'; $wb1 = $app.Workbooks.Open("..."); ...
The PowerShell executable takes a -Command parameter that allows you to specify a command string for execution in PowerShell:
powershell.exe -Command "stmnt1; stmnt2; ..."
To run this via Task Scheduler you'd put powershell.exe into the "program" field and -Command "stmnt1; stmnt2; ..." into the "arguments" field of the task.
However, as #alroc said: you should verify why script execution has been restricted. If it's just the default setting you can simply change it by running Set-ExecutionPolicy RemoteSigned or override it by adding -ExecutionPolicy ByPass to a PowerShell command line. However, if the setting is enforced by policy changing/bypassing the setting will fail, and you could get into quite some trouble for violating company policies.
Here is a solution that you might use if the script is not that easy to convert, but you are on Windows running at least PowerShell V5.
It converts the code into Base64 and uses PowerShell.exe with the parameter -encodedCommand to pass the encodedCommand as string.
$command = Get-Content .\YourPowerShellFileContainingTheCode.ps1 -raw
# Get-Content may require "-encoding utf8" or other encodings depending on your file
$encodedCommand = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($command))
Write-Output "Text for application:"
Write-Output "PowerShell.exe" ""
Write-Output "Text for argurments:"
Write-Output "-encodedCommand $encodedCommand"
It would look like this, but with a much larger command:
Text for application:
PowerShell.exe
Text for argurments:
-encodedCommand SABvACAASABvACAASABvACwAIABzAHQAYQBjAGsAbwB2AGUAcgBmAGwAbwB3AA==
From my script I want to run some command in remote Windows box. So I googled a little and seems the most popular and somehow standard way to do that is to use PowerShell's Invoke-Command cmdlet which seems to use the same protocol as winrm and winrs. So, bellow are commands I've tried to call from my script (actually I've tried lots of other their modifications as well, but IMO these are enough to illustrate the problem):
PowerShell -Command "$encpass=ConvertTo-SecureString -AsPlainText mypass -Force;$cred = New-Object System.Management.Automation.PSCredential -ArgumentList myuser,$encpass; Invoke-Command -ComputerName REMOTE_COMPUTER_NAME -Credential $cred -ScriptBlock {<fullcommand>};"
PowerShell -Command "$encpass=ConvertTo-SecureString -AsPlainText mypass -Force;$cred = New-Object System.Management.Automation.PSCredential -ArgumentList myuser,$encpass; Invoke-Command -ComputerName REMOTE_COMPUTER_NAME -Credential $cred -ScriptBlock {Start-Process -FilePath <fullexepath> -ArgumentList <arguments> -Wait -NoNewWindow};"
PowerShell -Command "$encpass=ConvertTo-SecureString -AsPlainText mypass -Force;$cred = New-Object System.Management.Automation.PSCredential -ArgumentList myuser,$encpass;$session=new-PSSession -ComputerName "REMOTE_COMPUTER_NAME" -Credential $cred; Invoke-Command -Session $session -ScriptBlock {<fullcommand>};"
NOTE: The script is written in perl, but IMO here the language of the script doesn't matter, so you can suppose that I call the command from batch script, just note, that as commands should run from a script they should not require any interactive actions.
So, I have several problems with these commands, and need help to figure them out. Here they are:
Can't run processes of type configure and run daemon. Namely if I want to run configure_server.pl on remote box (<fullcommand> = "configure_server.pl <arguments>"), which should do some stuff, then run server.exe, it doesn't work, because as soon as configure_server.pl is done, full remote job is being killed including the server.exe which supposed to run as a daemon. (applies to points 1,2,3)
Get wrapped (length of each line is less or equal than 80 chars) standard output and standard error. (applies to point 1,3)
Don't get standard output and standard error. (applies to point 2)
Whew this is a tough one, your kind of all over the place so if I miss what your trying to do completely let me know.
1 . Stop trying to go the remote route. I know it seems like a great idea, but it's not. The only way you can get the process to persist is if you keep the powershell window up on the host computer. As you've probably noticed, you can create processes fine, but they're children of your powershell.exe, and are hosted by the wsmprovhost.exe process on the client computer. Once the parent is gone, all the children are killed
To fix this I suggest using a command line function : Schtasks.exe
schtasks.exe /create /sc ONCE /tn $taskName /tr $command /s $serverName /u $userName /p $pass /ru $userName /rp $pass /st $startTime
This command is going to create a scheduled task to run once and then remove itself after. It even takes computer name, so no remote-access required. You can also do a schtasks.exe /query and check the "Status" for running before you do a schtasks.exe /delete too.
2 . Use the ` (backtick) to specify carry execution to the next line in powershell
3 . I get standard output and error with this function, sometimes not output when executed in a big script, but can always use $? to capture error.
Note: You cannot pass in PSCredentials to this command. I suggest making a GUI that just prompts for userName and and password, without converting to secure string. I try to stay away from remoting in my scripts, since it always just makes everything so slow. Sometimes you do not have a choice, but in this case I believe you do.
I was wondering if someone with more expertise could help me with a little problem I'm having with using Variables in -ArgumentList when using Start-Process.
If I run the Exe without using Start-Process
.\DeploymentServer.UI.CommandLine.exe register --estNumber $Number --postcode $PostCode --password $Password
everything works fine, the command runs and the software is registered.
If I try
Start-Process .\DeploymentServer.UI.CommandLine.exe -ArgumentList "register --estNumber $Number --postcode $PostCode --password $Password" -Wait -NoNewWindow
or
$Arguments = "register --estNumber $Number --postcode $PostCode --password $Password"
Start-Process .\DeploymentServer.UI.CommandLine.exe -ArgumentList $Arguments -NoNewWindow -Wait
the command runs but is unable to register, stating that it can not match the details provided. So I'm assuming the issue lies either in the passing of the arguments to Start-Process, or -ArgumentList interpreting the variables in the string. Am I missing something really simple here? Possibly to do with the $ in the -ArgumentList?
You have a space in your $postcode, so you need to put the argument in quotes:
Start-Process .\DeploymentServer.UI.CommandLine.exe -ArgumentList "register --estNumber $Number --postcode `"$PostCode`" --password $Password" -Wait -NoNewWindow
I encountered several posts online saying to wrap a Start-Process -ArgumentList argument containing spaces in 2 layers of doubles quotes, escaping the inner double quotes with a back tick `, but at least in the context I needed it, that didn't work. I found a conceptually similar solution which did work, however, i.e. a set of single quotes on the outside and a "traditional" backslash escape sequence on inner double quotes. I was guided to using this approach per this PowerShell issue post:
https://github.com/PowerShell/PowerShell/issues/5576
This example works for me (running a PS Start-Process command from cmd.exe):
C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe Start-Process -FilePath 'C:\Program Files (x86)\Example\Test.exe' -ArgumentList 'arg1','\"arg 2 w spaces\"','arg3'