Windows Powershell:导出用户权限分配

Windows Powershell:导出用户权限分配,windows,shell,powershell,batch-file,Windows,Shell,Powershell,Batch File,我是PowerShell(PS)的新手。目前我正在使用windows server 2012,我想知道是否有任何方法可以将用户权限分配导出到txt文件中。我试过了 secedit /export /areas USER_RIGHTS /cfg d:\policies.txt 以上内容应将其导出 所以,我明白了:。 是否有任何方法可以导出用户权限分配,并使其看起来像(即使使用批处理文件): p.S 在控制台中是否仍然可以输出这些值?因此,我可以将它们重定向到txt文件。下面是一个PowerShe

我是PowerShell(PS)的新手。目前我正在使用windows server 2012,我想知道是否有任何方法可以将
用户权限分配
导出到txt文件中。我试过了

secedit /export /areas USER_RIGHTS /cfg d:\policies.txt

以上内容应将其导出

所以,我明白了:。
是否有任何方法可以导出
用户权限分配
,并使其看起来像(即使使用批处理文件):

p.S

在控制台中是否仍然可以输出这些值?因此,我可以将它们重定向到txt文件。

下面是一个PowerShell脚本,它可以输出具有翻译名称和SID的可用对象:

#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

整个剧本很棒。谢谢你的努力。然而,为了让它输出所有被分配了权限的主体,我需要做的一个更改是将正则表达式更改为“^(Se\S+)=(.+)”,以便匹配已经用名称中的空格(如“域用户”)解析的主体。在此之前,它只会报告“域”

要将输出保存到文件,请在最后一个foreach对象的右括号后添加>>文件名 前任: } }>>“outFile.txt”

或使用以下命令作为分隔文件(如csv)输出:

}|转换为csv-分隔符“~”-notypeinformation>>“outFile.txt”


希望这有帮助

除了Eric的更改之外,我还需要在Bill_Stewart的帖子中的一个函数中添加一个try catch。如果要转换的SID来自不再存在的对象,则将返回SID,而不是发送转换错误

# 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))
    Try {$out = $sid.Translate([Security.Principal.NTAccount])}
    catch
        {
        $out = $principal
        }
    $out
  }
  else {
    $principal
  }
}

请编辑描述,并清楚地解释您粘贴的两个链接之间的差异。这将使读者明白这个问题。即使移除链接,读者仍然可以访问问题描述。抱歉,在EDIT中更改了链接。我可能会尝试帮助您,但我的公司阻止了所有文件下载站点,因此我无法查看您发布的任何链接。是否应该发布这些链接?@jonjoli-查看我的更新答案。抱歉,响应太晚,但这会提供与您相同的输出“secedit/export/areas USER\u RIGHTS/cfg d:\policies.txt”它将数据输出为对象,而不是文本,因此不,输出不“相同”。也许您需要澄清您的问题。如何将其输出为txt?您的意思是什么?请用您希望的输出外观更新您的问题(请不要链接-请在你的问题中直接粘贴一个示例)。在这种情况下你很幸运。我想我理解。请参阅更新的答案。