以管理员用户身份重新启动 PowerShell 脚本
Relaunching PowerShell script as admin user
我有很多计算机系统需要部署软件。我一直在使用一种简单的方法来检测用户是否是本地管理员,然后检测他们是否具有管理员权限。如果需要,脚本会以提升的权限重新启动。如果用户不是本地管理员,脚本将使用不同的凭据(本地管理员)重新启动。该脚本在具有更高版本的 PowerShell 的系统上运行良好,例如 Windows 8 和 Windows 10.
问题是当用户不是管理员并且脚本是 Windows 上的 运行 时 7. 脚本使用 $PSScriptPath
重新启动脚本。我认为这不适用于早期版本的 PowerShell。因此,如果主要 PowerShell 版本 < 3,我尝试自己设置 $PSScriptRoot
。问题是脚本陷入某种循环,它不断打开和关闭 windows,然后我必须杀了它...如果我不定义 $PSScriptRoot
我得到错误
Cannot bind argument to parameter 'Path' because it is null
我认为这是因为 $PSScriptRoot
未在 PowerShell 2.0 中定义。
这是我正在尝试做的一个例子:
#Check if PowerShell version is greater than 2. If not, set $PSSriptRoot.
if ($PSVersionTable.PSVersion.Major -lt 3) {
$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Definition
}
#Check if the user is a local admin. If they are, set $LocalAdmin to $True.
$LocalAdmin = $false
if ((net localgroup administrators) -match ([System.Environment]::UserDomainName + "\" + [System.Environment]::Username)) {
$LocalAdmin = $true
}
if ($LocalAdmin) {
#Check if the local admin needs to run the script as administrator
if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
$arguments = "& '" + $MyInvocation.MyCommand.Definition + "'"
Start-Process powershell -Verb runas -ArgumentList $arguments
break
}
} else {
#Not a local admin. Relaunch script as admin user.
Start-Process -Credential $credential (Join-Path $PSHome powershell.exe) -ArgumentList (@("-File",
(Join-Path $PSScriptRoot $MyInvocation.MyCommand)) + $args)
exit
}
不要重新定义 automatic variables。不会有好结果的。
此外,你为什么要这么做?您使用 $PSScriptRoot
的唯一目的是重建您已有的脚本路径。只需将该路径分配给一个变量并在您的脚本中使用它。
$script = $MyInvocation.MyCommand.Definition
$ps = Join-Path $PSHome 'powershell.exe'
$isLocalAdmin = [bool]((net localgroup administrators) -match "$env:USERDOMAIN\$env:USERNAME")
if ($isLocalAdmin) {
if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]'Administrator')) {
Start-Process $ps -Verb runas -ArgumentList "& '$script'"
exit
}
} else {
Start-Process $ps -ArgumentList (@('-File', $script) + $args) -Credential $credential
exit
}
我有很多计算机系统需要部署软件。我一直在使用一种简单的方法来检测用户是否是本地管理员,然后检测他们是否具有管理员权限。如果需要,脚本会以提升的权限重新启动。如果用户不是本地管理员,脚本将使用不同的凭据(本地管理员)重新启动。该脚本在具有更高版本的 PowerShell 的系统上运行良好,例如 Windows 8 和 Windows 10.
问题是当用户不是管理员并且脚本是 Windows 上的 运行 时 7. 脚本使用 $PSScriptPath
重新启动脚本。我认为这不适用于早期版本的 PowerShell。因此,如果主要 PowerShell 版本 < 3,我尝试自己设置 $PSScriptRoot
。问题是脚本陷入某种循环,它不断打开和关闭 windows,然后我必须杀了它...如果我不定义 $PSScriptRoot
我得到错误
Cannot bind argument to parameter 'Path' because it is null
我认为这是因为 $PSScriptRoot
未在 PowerShell 2.0 中定义。
这是我正在尝试做的一个例子:
#Check if PowerShell version is greater than 2. If not, set $PSSriptRoot.
if ($PSVersionTable.PSVersion.Major -lt 3) {
$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Definition
}
#Check if the user is a local admin. If they are, set $LocalAdmin to $True.
$LocalAdmin = $false
if ((net localgroup administrators) -match ([System.Environment]::UserDomainName + "\" + [System.Environment]::Username)) {
$LocalAdmin = $true
}
if ($LocalAdmin) {
#Check if the local admin needs to run the script as administrator
if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
$arguments = "& '" + $MyInvocation.MyCommand.Definition + "'"
Start-Process powershell -Verb runas -ArgumentList $arguments
break
}
} else {
#Not a local admin. Relaunch script as admin user.
Start-Process -Credential $credential (Join-Path $PSHome powershell.exe) -ArgumentList (@("-File",
(Join-Path $PSScriptRoot $MyInvocation.MyCommand)) + $args)
exit
}
不要重新定义 automatic variables。不会有好结果的。
此外,你为什么要这么做?您使用 $PSScriptRoot
的唯一目的是重建您已有的脚本路径。只需将该路径分配给一个变量并在您的脚本中使用它。
$script = $MyInvocation.MyCommand.Definition
$ps = Join-Path $PSHome 'powershell.exe'
$isLocalAdmin = [bool]((net localgroup administrators) -match "$env:USERDOMAIN\$env:USERNAME")
if ($isLocalAdmin) {
if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]'Administrator')) {
Start-Process $ps -Verb runas -ArgumentList "& '$script'"
exit
}
} else {
Start-Process $ps -ArgumentList (@('-File', $script) + $args) -Credential $credential
exit
}