将参数传递给 Powershell 脚本
Passing arguments to Powershell script
我有一个最多接受 3 个参数的脚本 - 用户名、密码和发行版。
该脚本需要 运行 管理员身份,因为它会检查某些功能是否已启用并且只能以管理员身份完成。
# the command line is:
# linux-docker <username> <password> <distro>
# if no distro is specified then Debian is used.
param ([Parameter(Mandatory)]$username, [Parameter(Mandatory)]$password, $distro='Debian')
# check if we are in admin mode and switch if we aren't
$currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
if (-Not $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs;
Read-Host -Prompt "Failure: Press Enter to exit"
exit;
}
}
# ... rest of script
但是重新启动脚本会提示用户输入用户名和密码。我想将参数传递给提升的脚本。
我首先想到的是在Start-Process
命令中添加$username
、$password
和$distro
。
Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`" $username $password $debian" -Verb RunAs;
但退出时显示“失败”消息。
所以我查看了 -ArgumentList
但它死于处理该行:
Start-Process : A positional parameter cannot be found that accepts argument '-NoProfile -ExecutionPolicy Bypass -File "C:\Users\Graham Reeds\Documents\linux-docker.ps1"'.
At C:\Users\Graham Reeds\Documents\linux-docker.ps1:15 char:9
+ Start-Process powershell.exe "-NoProfile -ExecutionPolicy Byp ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Start-Process], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.StartProcessCommand
Failure: Press Enter to exit:
这可能很简单,但我是 Powershell 的菜鸟。
使用-ArgumentList
参数应该可以,但是对于发送到脚本的参数,你需要
从 BoundParameters 哈希中获取它们的名称和值:
$currentPrincipal = [Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()
$isAdmin = $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
if (!$isAdmin) {
$argList = '-NoLogo', '-NoProfile', '-NoExit', '-ExecutionPolicy Bypass', '-File', ('"{0}"' -f $PSCommandPath)
# Add script arguments
$argList += $MyInvocation.BoundParameters.GetEnumerator() | ForEach-Object {"-$($_.Key)", "$($_.Value)"}
try {
Start-Process PowerShell.exe -WorkingDirectory $pwd.ProviderPath -ArgumentList $argList -Verb Runas -ErrorAction Stop
# exit the current script
exit
}
catch {
Write-Warning "Failed to restart script '$PSCommandPath' with runas"
}
}
# rest of the script
P.S。我个人喜欢总是使用 type-cast 参数,并在可能的情况下明确说明如果不使用强制参数,应按什么顺序给出 Named:
param (
[Parameter(Mandatory = $true, Position = 0)][string] $username,
[Parameter(Mandatory = $true, Position = 1)][string] $password,
[string] $distro='Debian'
)
我有一个最多接受 3 个参数的脚本 - 用户名、密码和发行版。
该脚本需要 运行 管理员身份,因为它会检查某些功能是否已启用并且只能以管理员身份完成。
# the command line is:
# linux-docker <username> <password> <distro>
# if no distro is specified then Debian is used.
param ([Parameter(Mandatory)]$username, [Parameter(Mandatory)]$password, $distro='Debian')
# check if we are in admin mode and switch if we aren't
$currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
if (-Not $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs;
Read-Host -Prompt "Failure: Press Enter to exit"
exit;
}
}
# ... rest of script
但是重新启动脚本会提示用户输入用户名和密码。我想将参数传递给提升的脚本。
我首先想到的是在Start-Process
命令中添加$username
、$password
和$distro
。
Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`" $username $password $debian" -Verb RunAs;
但退出时显示“失败”消息。
所以我查看了 -ArgumentList
但它死于处理该行:
Start-Process : A positional parameter cannot be found that accepts argument '-NoProfile -ExecutionPolicy Bypass -File "C:\Users\Graham Reeds\Documents\linux-docker.ps1"'.
At C:\Users\Graham Reeds\Documents\linux-docker.ps1:15 char:9
+ Start-Process powershell.exe "-NoProfile -ExecutionPolicy Byp ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Start-Process], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.StartProcessCommand
Failure: Press Enter to exit:
这可能很简单,但我是 Powershell 的菜鸟。
使用-ArgumentList
参数应该可以,但是对于发送到脚本的参数,你需要
从 BoundParameters 哈希中获取它们的名称和值:
$currentPrincipal = [Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()
$isAdmin = $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
if (!$isAdmin) {
$argList = '-NoLogo', '-NoProfile', '-NoExit', '-ExecutionPolicy Bypass', '-File', ('"{0}"' -f $PSCommandPath)
# Add script arguments
$argList += $MyInvocation.BoundParameters.GetEnumerator() | ForEach-Object {"-$($_.Key)", "$($_.Value)"}
try {
Start-Process PowerShell.exe -WorkingDirectory $pwd.ProviderPath -ArgumentList $argList -Verb Runas -ErrorAction Stop
# exit the current script
exit
}
catch {
Write-Warning "Failed to restart script '$PSCommandPath' with runas"
}
}
# rest of the script
P.S。我个人喜欢总是使用 type-cast 参数,并在可能的情况下明确说明如果不使用强制参数,应按什么顺序给出 Named:
param (
[Parameter(Mandatory = $true, Position = 0)][string] $username,
[Parameter(Mandatory = $true, Position = 1)][string] $password,
[string] $distro='Debian'
)