I was struggling to get this simple (?) function working today.
I have a PowerShell script that reads computer names from a txt-based file. It works fine when run from a PowerShell session by the following one-liner:
./"Server Health Check.ps1" -List One-off.txt
As you can see, it's got a long file name, so it's wrapped with quotes.
However, I'm building a PowerShell GUI form with radio boxes that will pass on a choice for a text file that will be used to a call the script. Trick is, the script needs to be run with alternate admin account, and i'm not clear how to make that work.
For another script I've got that doesn't use I know i can use something along the lines of the following, this uses the old DOS "runas", however, it doesn't work with the -list function.
invoke-command -scriptblock {runas.exe /user:domain\$Env:Username"admin" "powershell.exe -file \"\\Server\c$\LONG FOLDER\Server Health Check.PS1""}
So, in a nutshell, how do get a script to launch with alternate credentials that reads a parameter (-List) from the command line? I'm also keen to preserve my directory structure, which includes folders with spaces. The script is titled: "Server health check.ps1"
The last thing I tried was the following
$ScriptPath = "C:\SCRIPTS FOLDER\Server Health Check.ps1"
$ArgList = "-List C:\SCRIPTS FOLDER\One-off.txt"
Invoke-Command -filepath $ScriptPath -Credential DragonBallDomain\$Env:UserName"Admin" -ArgumentList $ArgList
The result was the following message:
Invoke-Command : Parameter set cannot be resolved using the specified named parameters.
I'm almost certain this is do-able by invoke-command or start-process, it's just a matter of getting the correct formatting? I'm probably missing a / or a ' or "" somewhere in my trials with start-process or invoke-command.
Any help appreciated!
Update for April 30:
I've tried some more to make this work, i'm close, but still not quite there.
$LongScriptPath = resolve-path Script.ps1
$LongFolderPath = \\UNC\PATH TO FOLDER\WITH LONG NAME\
start-process -filepath powershell.exe -argumentlist " -file``"$($FilePath.path)`"" -cred DOMAIN\USERID -WorkingDirectory "$LongFolderPath"
Adding the -credential is what causes an error that states that the -file parameter is invalid. I'm sure there's a way to do this.
Note: Completely rewritten after the requirements became clearer.
To run a command as a different user locally, use Start-Process -Credential ...
That is what you've attempted in your update in principle, but there are problems with how you're passing parameters; try this instead:
$LongScriptPath = resolve-path Script.ps1
$LongFolderPath = '\\UNC\PATH TO FOLDER\WITH LONG NAME\'
start-process `
powershell.exe `
-ArgumentList '-file', $LongScriptPath, '-List', 'One-off.txt' `
-Credential DOMAIN\USERID `
-WorkingDirectory $LongFolderPath
The key to making this work is to pass all parameters to pass to powershell.exe
as an array via Start-Process
's -ArgumentList
parameter, which means that the parameters must be ,
-separated.
-file
and -List
must be quoted.Add -Wait
to wait for the script to finish; Start-Process
is asynchronous by default (all PS cmdlets named Start-*
are).
Access denied
error message in the current console; in effect, -Wait
is ignored.Only if not running as a different user: Add -NoNewWindow -Wait
if you want to run the script in the current console window; Start-Process
opens a new window by default for console applications such as powershell.exe
and cmd.exe
.
-NoNewWindow
is quietly ignored.As for the original symptom and why using Invoke-Command
to run a command locally as a different user is ill-advised:
Invoke-Command -Credential ...
requires that the -ComputerName
parameter be specified too.
Get-Help Invoke-Command
to see all parameter sets that involve the -Credential
parameter. The OP's original command had only -Credential
, but not -ComputerName
, which caused PS to complain that no parameter set could be unambiguously identified.Once you use -ComputerName
, PowerShell remoting is invariably used, even if you specify .
- the local computer - as the only computer to target.
In short:
While you can perform purely local invocations with Invoke-Command
, you cannot do so as another user, because that invariably involves remoting.
Start-Process
, by contrast, solely exists to run commands locally, optionally as a different user.