Powershell: Export User Rights Assignment

后端 未结 2 786
夕颜
夕颜 2021-01-22 07:12

I\'m new to PowerShell (PS). Currently I\'m using windows server 2012 and I\'m interested to know whether there is any way to export User Rights Assignment into a t

相关标签:
2条回答
  • 2021-01-22 07:48

    Here's a PowerShell script that outputs usable objects with translated names and SIDs:

    #requires -version 2
    
    # Fail script if we can't find SecEdit.exe
    $SecEdit = Join-Path ([Environment]::GetFolderPath([Environment+SpecialFolder]::System)) "SecEdit.exe"
    if ( -not (Test-Path $SecEdit) ) {
      Write-Error "File not found - '$SecEdit'" -Category ObjectNotFound
      exit
    }
    
    # LookupPrivilegeDisplayName Win32 API doesn't resolve logon right display
    # names, so use this hashtable
    $UserLogonRights = @{
      "SeBatchLogonRight"                 = "Log on as a batch job"
      "SeDenyBatchLogonRight"             = "Deny log on as a batch job"
      "SeDenyInteractiveLogonRight"       = "Deny log on locally"
      "SeDenyNetworkLogonRight"           = "Deny access to this computer from the network"
      "SeDenyRemoteInteractiveLogonRight" = "Deny log on through Remote Desktop Services"
      "SeDenyServiceLogonRight"           = "Deny log on as a service"
      "SeInteractiveLogonRight"           = "Allow log on locally"
      "SeNetworkLogonRight"               = "Access this computer from the network"
      "SeRemoteInteractiveLogonRight"     = "Allow log on through Remote Desktop Services"
      "SeServiceLogonRight"               = "Log on as a service"
    }
    
    # Create type to invoke LookupPrivilegeDisplayName Win32 API
    $Win32APISignature = @'
    [DllImport("advapi32.dll", SetLastError=true)]
    public static extern bool LookupPrivilegeDisplayName(
      string systemName,
      string privilegeName,
      System.Text.StringBuilder displayName,
      ref uint cbDisplayName,
      out uint languageId
    );
    '@
    $AdvApi32 = Add-Type advapi32 $Win32APISignature -Namespace LookupPrivilegeDisplayName -PassThru
    
    # Use LookupPrivilegeDisplayName Win32 API to get display name of privilege
    # (except for user logon rights)
    function Get-PrivilegeDisplayName {
      param(
        [String] $name
      )
      $displayNameSB = New-Object System.Text.StringBuilder 1024
      $languageId = 0
      $ok = $AdvApi32::LookupPrivilegeDisplayName($null, $name, $displayNameSB, [Ref] $displayNameSB.Capacity, [Ref] $languageId)
      if ( $ok ) {
        $displayNameSB.ToString()
      }
      else {
        # Doesn't lookup logon rights, so use hashtable for that
        if ( $UserLogonRights[$name] ) {
          $UserLogonRights[$name]
        }
        else {
          $name
        }
      }
    }
    
    # Outputs list of hashtables as a PSObject
    function Out-Object {
      param(
        [System.Collections.Hashtable[]] $hashData
      )
      $order = @()
      $result = @{}
      $hashData | ForEach-Object {
        $order += ($_.Keys -as [Array])[0]
        $result += $_
      }
      New-Object PSObject -Property $result | Select-Object $order
    }
    
    # Translates a SID in the form *S-1-5-... to its account name;
    function Get-AccountName {
      param(
        [String] $principal
      )
      if ( $principal[0] -eq "*" ) {
        $sid = New-Object System.Security.Principal.SecurityIdentifier($principal.Substring(1))
        $sid.Translate([Security.Principal.NTAccount])
      }
      else {
        $principal
      }
    }
    
    $TemplateFilename = Join-Path ([IO.Path]::GetTempPath()) ([IO.Path]::GetRandomFileName())
    $LogFilename = Join-Path ([IO.Path]::GetTempPath()) ([IO.Path]::GetRandomFileName())
    $StdOut = & $SecEdit /export /cfg $TemplateFilename /areas USER_RIGHTS /log $LogFilename
    if ( $LASTEXITCODE -eq 0 ) {
      Select-String '^(Se\S+) = (\S+)' $TemplateFilename | Foreach-Object {
        $Privilege = $_.Matches[0].Groups[1].Value
        $Principals = $_.Matches[0].Groups[2].Value -split ','
        foreach ( $Principal in $Principals ) {
          Out-Object `
            @{"Privilege" = $Privilege},
            @{"PrivilegeName" = Get-PrivilegeDisplayName $Privilege},
            @{"Principal" = Get-AccountName $Principal}
        }
      }
    }
    else {
      $OFS = ""
      Write-Error "$StdOut"
    }
    Remove-Item $TemplateFilename,$LogFilename -ErrorAction SilentlyContinue
    
    0 讨论(0)
  • 2021-01-22 07:59

    Great script overall. Thank you for your efforts. One change I needed to make however to get it to output all principals assigned a right was to change the regex to '^(Se\S+) = (.+)' so that principals that were already resolved with a space in the name such as 'Domain users' were matched. Before that it would just report 'Domain.'

    To save the output to a file, add a >> filename after the closing bracket of the last foreach-object Ex: } } >> 'outFile.txt'

    or to output as delimited file (e.g., csv) use the following:

    } | convertto-csv -delimiter '~' -notypeinformation >> 'outFile.txt'

    Hope this helps.

    0 讨论(0)
提交回复
热议问题