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
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
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.