Wednesday, February 13, 2008

WinSxS and Format-Sddl

While cleaning up on my harddisk - how come that I always run out of space not matter how big it is? - I came across the 5 GB in \Windows\winsxs. So could I get rid of these? Surfing the net, I found this article, and no, this seems to be yet another internal Windows folder that you just have to live with. Well the article showed the security of the folder in SDDL format and I liked that format, so why not create a PowerShell script, that could format an SDDL string in the same, readable way? And while I was at it: Why not translate SIDs to account names? As thought, then done -

# Format SDDL strings in a more readable format
# If -TranslateSid is present, Sids will be translated to their account equivalent
param([switch]$translateSid)
process {
$sddl=$_
if ($sddl -is [string]) {
# Simply use the value
}
else {
# If input is any thing else, pick up SDDL property
# This makes it possible to pipe in the output from Get-Acl or Select
$sddl=$_.sddl
}
# Insert linefeed before G: D: or S: blocks
# Insert linefeed and indent values in ()
$sddl=$sddl -replace "([GDS]):","`n`$1:" -replace "(\([^\)]+\))","`n `$1"
if ($translateSid.isPresent) {
# Match all SIDs and translate them to NTAccount format
[regex]::Matches($sddl,"(S(-\d+){2,8})") | sort index -desc | % {
# Save value in case translatation fails
$name=$_.value
$sid=[system.security.principal.securityidentifier] $name
# Remove matched value
$sddl=$sddl.remove($_.index,$_.length)
# Translate, suppress non-translatable exception
trap [System.Management.Automation.MethodInvocationException] {continue} `
$name=$sid.Translate([system.security.principal.ntaccount])
# Insert translated name
$sddl=$sddl.insert($_.index,$name)
}
}
$sddl
}


 



The script shows a couple of techniques -




  • Testing the type of pipeline input and using it accordingly


  • Use of regular expressions for replacement and picking up values from the matched values ($1)


  • Use of the regex object to walk-through the matched values. This is necessary in cases where the new value needs to be calculated.


  • How to translate a SID string to an account name using the .Net classes in system.security.principal namespace


  • How to suppress a specific exception using a trap statement



 



Example of how to use it -



image



Have fun!

No comments: