【问题标题】:How can I run powershell script that uses both local & elevated permissions?如何运行同时使用本地和提升权限的 powershell 脚本?
【发布时间】:2020-02-28 18:24:33
【问题描述】:

我需要编辑两个注册表项。一个需要由本地用户运行,另一个需要由具有提升权限的帐户运行。

我如何编写一个以其他用户身份运行但仍可以访问本地用户凭据的脚本?

【问题讨论】:

    标签: powershell


    【解决方案1】:

    作为管理员,您也可以为当前登录的用户设置注册表值,前提是您可以获得该用户的 SID。 当你拥有它时,你可以通过HKEY_USERS hive 访问本地用户注册表。

    Import-Module ActiveDirectory
    
    # set this to the registry path, property name and value you need to access
    $regPath   = 'Software\SomePath\SomeKey'
    $propName  = 'ThePropertyName'
    $propValue = 'ThePropertyValue'
    $propType  = 'String'           # use any of the `[Microsoft.Win32.RegistryValueKind]` enum values or names
    
    # get the domain\username of the user currently logged in to the computer
    $user = (Get-CimInstance -ClassName Win32_ComputerSystem).UserName
    # get the SID for that user 
    $sid = (Get-ADUser -Identity ($user -split '\\', 2)[0]).SID
    if (!$sid) {
        throw "Could not determine the SID for user '$user'"
    }
    
    # Admin registry: HKEY_LOCAL_MACHINE
    $path = Join-Path -Path 'HKLM:' -ChildPath $regPath
    Set-Itemproperty -Path $path -Name $propName -Value $propValue -Type $propType
    
    # Current user registry: HKEY_USERS
    $path = Join-Path -Path "Registry::HKEY_USERS\$sid" -ChildPath $regPath
    Set-Itemproperty -Path $path -Name $propName -Value $propValue -Type $propType
    

    正如mklement0 评论的那样, 上述代码使用ActiveDirectory 模块通过Get-ADUser 获取当前登录用户的SID。
    如果您无法做到这一点,或者您不在 AD 域中,则以下帮助函数也可以获取 SID,而无需 ActiveDirectory:

    function Get-UserSID {
        param (
            [Parameter(ValuefromPipeline = $true, Position = 0)]
            [Alias('Account', 'User')]
            [string]$UserName = $env:USERNAME,
            [string]$Domain   = $env:USERDOMAIN
        )
        if ($UserName.Contains("\")) { $Domain, $UserName = $UserName -split '\\', 2 }   #"# split on the backslash
        try {
            $objUser = New-Object System.Security.Principal.NTAccount($Domain, $UserName)
            $strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier])
            $strSID.Value
        }
        catch [System.Security.Principal.IdentityNotMappedException] {
            Write-Warning "User '$UserName' does not exist in '$Domain'"
        }
        catch {
            throw
        }
    }
    

    把它放在你的脚本之上,然后用作:

    # get the domain\username of the user currently logged in to the computer
    $user = (Get-CimInstance -ClassName Win32_ComputerSystem).UserName
    # get the SID for that user 
    $sid = Get-UserSID $user
    

    获取 SID 的第三种可能方法是读取注册表:

    # get the domain\username of the user currently logged in to the computer
    $user = (Get-CimInstance -ClassName Win32_ComputerSystem).UserName
    # get the SID for that user by probing the registry
    $sid = ((Get-ItemProperty -Path 'Registry::HKEY_USERS\S-*\Volatile Environment' |
             Where-Object { ('{0}\{1}' -f $_.USERDOMAIN, $_.USERNAME) -eq $user }).PSParentPath -split '\\')[-1]
    

    【讨论】:

    • 感谢更新,Theo - 很棒的替代品(不知道注册表方法 - 或许值得一提的是,它仅适用于 当前登录 用户,如果我正确理解)。最后的想法:我建议避免使用伪方法语法:而不是New-Object SomeType(arg1, ...),使用New-Object SomeType [-ArgumentList] arg1, ...
    【解决方案2】:

    您可以使用键“-credential”来设置将更改注册表的用户,例如:

    New-Item –Path "HKCU:\dummy" –Name newregistrykey -Credential myuser@domain
    

    或设置属性:

    Set-Itemproperty -path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run' -Name 'someProcess' -value 'C:\Program Files\someapp\myprogramm.exe' -Credential myuser@domain
    

    您可以将双方的信誉保存到以下变量中:

    $localCred = Get-Credential
    $domainCred = Get-Credential
    

    【讨论】:

      猜你喜欢
      • 2021-06-22
      • 2021-04-17
      • 2021-01-09
      • 2018-04-21
      • 1970-01-01
      • 1970-01-01
      • 2022-01-14
      • 2013-11-09
      相关资源
      最近更新 更多