{"id":2390,"date":"2012-06-21T11:09:55","date_gmt":"2012-06-21T15:09:55","guid":{"rendered":"http:\/\/jdhitsolutions.com\/blog\/?p=2390"},"modified":"2012-06-21T11:17:05","modified_gmt":"2012-06-21T15:17:05","slug":"get-acl-information-with-powershell","status":"publish","type":"post","link":"https:\/\/jdhitsolutions.com\/blog\/powershell\/2390\/get-acl-information-with-powershell\/","title":{"rendered":"Get ACL Information with PowerShell"},"content":{"rendered":"<p>I got a question in the <a href=\"http:\/\/bit.ly\/AskJeffHicks\" title=\"Visit the forum\" target=\"_blank\">\"Ask Don and Jeff\"<\/a> forum on PowerShell.com that intrigued me. The issue was working with the results of the Get-ACL cmdlet. The resulting object includes a property called Access which is a collection of access rule objects. Assuming you are using this with the file system, these are System.Security.AccessControl.FileSystemAccessRule objects that look like this:<\/p>\n<p>FileSystemRights  : ReadAndExecute, Synchronize<br \/>\nAccessControlType : Allow<br \/>\nIdentityReference : BUILTIN\\Users<br \/>\nIsInherited       : False<br \/>\nInheritanceFlags  : ContainerInherit, ObjectInherit<br \/>\nPropagationFlags  : None<\/p>\n<p>If I'm understanding the original problem, the poster wanted to identify folders that had a single non-system entry. That is, a folder where someone added a single entry. It doesn't matter who. So this got me to thinking about a tool that would look at a folder ACL and report on how many access rules were found and then break that count down by system and user. I figured that any rule where the identity reference name included \"Builtin\", \"NT Authority\", \"Everyone\" or \"Creator Owner\" would be considered a system rule. Anything else would be considered a user rule. <\/p>\n<p>In the console, I could run a command like this:<\/p>\n<p><code lang=\"DOS\"><br \/>\nPS S:\\> get-acl c:\\work | select -expand access | where {$_.identityreference -notmatch \"BUILTIN|NT AUTHORITY|EVERYONE|CREATOR OWNER\"}<\/p>\n<p>FileSystemRights  : FullControl<br \/>\nAccessControlType : Allow<br \/>\nIdentityReference : SERENITY\\Jeff<br \/>\nIsInherited       : False<br \/>\nInheritanceFlags  : None<br \/>\nPropagationFlags  : None<br \/>\n<\/code><\/p>\n<p>Because I ran this interactively, I know what folder has this potential issue. So the next step is to turn this into a tool that will write ACL summary information to the pipeline. Here's my function, and then I'll explain a few things. The download version includes comment based help.<\/p>\n<p><code lang=\"PowerShell\"><br \/>\nFunction Get-ACLInfo {<\/p>\n<p>[cmdletbinding()]<\/p>\n<p>Param(<br \/>\n[Parameter(Position=0,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)]<br \/>\n[ValidateScript({Test-Path $_})]<br \/>\n[Alias('PSPath','Fullname')]<br \/>\n[string[]]$Path=\".\"<br \/>\n)<\/p>\n<p>Begin {<br \/>\n    Write-Verbose \"Starting $($myinvocation.mycommand)\"<\/p>\n<p>    #create a format file on the fly<br \/>\n    $xml=@\"<br \/>\n<?xml version=\"1.0\" encoding=\"utf-8\" ?><br \/>\n<Configuration><br \/>\n    <ViewDefinitions><br \/>\n        <View><br \/>\n            <Name>JDH.ACLInfo<\/Name><br \/>\n            <ViewSelectedBy><br \/>\n                <TypeName>JDH.ACLInfo<\/TypeName><br \/>\n            <\/ViewSelectedBy><br \/>\n            <TableControl><br \/>\n                <TableHeaders><br \/>\n                    <TableColumnHeader><br \/>\n                        <Width>50<\/Width><br \/>\n\t\t\t\t\t<\/TableColumnHeader><br \/>\n                    <TableColumnHeader\/><br \/>\n                    <TableColumnHeader><br \/>\n                      <Width>8<\/Width><br \/>\n                    <\/TableColumnHeader><br \/>\n\t\t\t\t\t<TableColumnHeader><br \/>\n                      <Width>9<\/Width><br \/>\n                    <\/TableColumnHeader><br \/>\n                    <TableColumnHeader><br \/>\n                        <Width>7<\/Width><br \/>\n                    <\/TableColumnHeader><br \/>\n                <\/TableHeaders><br \/>\n                <TableRowEntries><br \/>\n                    <TableRowEntry><br \/>\n                        <TableColumnItems><br \/>\n                            <TableColumnItem><br \/>\n                                <PropertyName>Path<\/PropertyName><br \/>\n                            <\/TableColumnItem><br \/>\n                            <TableColumnItem><br \/>\n                                <PropertyName>Owner<\/PropertyName><br \/>\n                            <\/TableColumnItem><br \/>\n                            <TableColumnItem><br \/>\n                                <PropertyName>TotalACL<\/PropertyName><br \/>\n                            <\/TableColumnItem><br \/>\n                            <TableColumnItem><br \/>\n                                <Propertyname>SystemACL<\/Propertyname><br \/>\n                            <\/TableColumnItem><br \/>\n                             <TableColumnItem><br \/>\n                                <Propertyname>UserACL<\/Propertyname><br \/>\n                            <\/TableColumnItem><br \/>\n                        <\/TableColumnItems><br \/>\n                    <\/TableRowEntry><br \/>\n                 <\/TableRowEntries><br \/>\n            <\/TableControl><br \/>\n        <\/View><br \/>\n    <\/ViewDefinitions><br \/>\n<\/Configuration><br \/>\n\"@<br \/>\n    #create a temp file<br \/>\n    $tmpfile=[system.io.path]::GetTempFileName()<br \/>\n    #add the necessary file extension<br \/>\n    $tmpfile+=\".ps1xml\"<\/p>\n<p>    #pipe the xml text to the temp file<br \/>\n    Write-Verbose \"Creating $tmpfile\"<br \/>\n    $xml | Out-File -FilePath $tmpfile<\/p>\n<p>    <#\n     update format data. I'm setting error action to SilentlyContinue\n     because everytime you run the function it creates a new temp file\n     but Update-FormatData tries to reload all the format files it \n     knows about in the current session, which includes previous versions\n     of this file which have already been deleted.\n    #><br \/>\n    Write-Verbose \"Updating format data\"<br \/>\n    Update-FormatData -AppendPath $tmpfile -ErrorAction SilentlyContinue<\/p>\n<p>} #Begin<\/p>\n<p>Process {<br \/>\n    Foreach ($folder in $path) {<br \/>\n        Write-Verbose \"Getting ACL for $folder\"<br \/>\n        #get the folder ACL<br \/>\n        $acl=Get-ACL -Path $path<\/p>\n<p>        #a regex to get a file path<br \/>\n        [regex]$regex=\"\\w:\\\\\\S+\"<\/p>\n<p>        #get full path from ACL object<br \/>\n        $folderpath=$regex.match($acl.path).Value<\/p>\n<p>        #get Access rules<br \/>\n        $access=$acl.Access<\/p>\n<p>        #get builtin and system ACLS<br \/>\n        $sysACL=$access | where {$_.identityreference -match \"BUILTIN|NT AUTHORITY|EVERYONE|CREATOR OWNER\"}<\/p>\n<p>        #get non builtin and system ACLS<br \/>\n        $nonSysACL=$access | where {$_.identityreference -notmatch \"BUILTIN|NT AUTHORITY|EVERYONE|CREATOR OWNER\"}<\/p>\n<p>        #grab some properties and add them to a hash table.<br \/>\n        $hash=@{<br \/>\n            Path=$folderpath<br \/>\n            Owner=$acl.Owner<br \/>\n            TotalACL=$access.count<br \/>\n            SystemACL=($sysACL | measure-object).Count<br \/>\n            UserACL=($nonSysACL | measure-object).Count<br \/>\n            AccessRules=$access<br \/>\n        }<\/p>\n<p>        #write a new object to the pipeline<br \/>\n        $obj=New-object -TypeName PSObject -Property $hash<br \/>\n        #add a type name for the format file<br \/>\n        $obj.PSObject.TypeNames.Insert(0,'JDH.ACLInfo')<br \/>\n        $obj<\/p>\n<p>    } #foreach<\/p>\n<p>} #Process<\/p>\n<p>End {<br \/>\n    #delete the temp file if it still exists<br \/>\n    if (Test-Path $tmpfile) {<br \/>\n        Write-Verbose \"Deleting $tmpfile\"<br \/>\n        Remove-Item -Path $tmpFile<br \/>\n    }<br \/>\n    Write-Verbose \"Ending $($myinvocation.mycommand)\"<br \/>\n} #end<\/p>\n<p>} #end function<br \/>\n<\/code><\/p>\n<p>When I run the function here's what the result looks like:<\/p>\n<p><code lang=\"DOS\"><br \/>\nPS S:\\> get-aclinfo | select *<\/p>\n<p>SystemACL   : 7<br \/>\nOwner       : SERENITY\\Jeff<br \/>\nUserACL     : 0<br \/>\nAccessRules : {System.Security.AccessControl.FileSystemAccessRule, System.Security.AccessControl.Fi<br \/>\n              leSystemAccessRule, System.Security.AccessControl.FileSystemAccessRule, System.Securi<br \/>\n              ty.AccessControl.FileSystemAccessRule...}<br \/>\nPath        : C:\\scripts\\<br \/>\nTotalACL    : 7<br \/>\n<\/code><\/p>\n<p>The function takes a path parameter and passes that to Get-ACL.<\/p>\n<p><code lang=\"PowerShell\"><br \/>\n$acl=Get-ACL -Path $path<br \/>\n<\/code><\/p>\n<p>I will be using some of the properties of this object in the custom object I'll eventually write to the pipeline. One thing I want is the full path. Unfortunately, I need to parse that out of the path property. I decided to use a regular expression.<\/p>\n<p><code lang=\"PowerShell\"><br \/>\n#a regex to get a file path<br \/>\n[regex]$regex=\"\\w:\\\\\\S+\"<\/p>\n<p>#get full path from ACL object<br \/>\n$folderpath=$regex.match($acl.path).Value<br \/>\n<\/code><\/p>\n<p>Next, I need to count the access rule entries and determine which are system and which are user.<\/p>\n<p><code lang=\"PowerShell\"><br \/>\n#get Access rules<br \/>\n$access=$acl.Access<\/p>\n<p>#get builtin and system ACLS<br \/>\n$sysACL=$access | where {$_.identityreference -match \"BUILTIN|NT AUTHORITY|EVERYONE|CREATOR OWNER\"}<\/p>\n<p>#get non builtin and system ACLS<br \/>\n$nonSysACL=$access | where {$_.identityreference -notmatch \"BUILTIN|NT AUTHORITY|EVERYONE|CREATOR OWNER\"}<br \/>\n<\/code><\/p>\n<p>I like creating new objects with hash tables, which will get even easier in PowerShell 3.0.<\/p>\n<p><code lang=\"PowerShell\"><br \/>\n#grab some properties and add them to a hash table.<br \/>\n$hash=@{<br \/>\n    Path=$folderpath<br \/>\n    Owner=$acl.Owner<br \/>\n    TotalACL=$access.count<br \/>\n    SystemACL=($sysACL | measure-object).Count<br \/>\n    UserACL=($nonSysACL | measure-object).Count<br \/>\n    AccessRules=$access<br \/>\n}<\/p>\n<p>#write a new object to the pipeline<br \/>\n$obj=New-object -TypeName PSObject -Property $hash<br \/>\n<\/code><\/p>\n<p>The object shows counts of the different ACL \"types\" and also includes a property with the full access rules should you want to look at them in more detail. But now for the \"scoop of ice cream on the side\" part of this function.<\/p>\n<p>In PowerShell 2.0, hash tables are unordered meaning there's no guarantee what order your properties will be display. Plus, you may want to have more control over how PowerShell formats the resulting objects. The way we handle this is by creating a format file and loading it into the shell with Update-FormatData. I'm not going to go into the mechanics of custom format files here. I know the topic is covered in the Windows PowerShell 2.0: TFM book, and the Month of Lunches books among others.<\/p>\n<p>Now, if I had created a module out of this function I could have packaged it with a separate format ps1xml file. But I had a thought of trying to use a format file \"on the fly\". In the Begin script block, I have the XML that would normally go into the format.ps1xml file. I create a temp file and add the xml to it.<\/p>\n<p><code lang=\"PowerShell\"><br \/>\n#create a temp file<br \/>\n$tmpfile=[system.io.path]::GetTempFileName()<br \/>\n#add the necessary file extension<br \/>\n$tmpfile+=\".ps1xml\"<\/p>\n<p>#pipe the xml text to the temp file<br \/>\nWrite-Verbose \"Creating $tmpfile\"<br \/>\n$xml | Out-File -FilePath $tmpfile<br \/>\n<\/code><\/p>\n<p>The format file apparently needs to have .ps1xml file extension so I have to update the file name. Once I have this file, I call Update-FormatData to load it.<\/p>\n<p><code lang=\"PowerShell\"><br \/>\nUpdate-FormatData -AppendPath $tmpfile -ErrorAction SilentlyContinue<br \/>\n<\/code><\/p>\n<p>Normally, I'm not a big fan of turning off errors, but in this case I need to. When you run Update-FormatData, PowerShell reloads all the format files that it knows in this session. The first time I run the function, the temp file is created and loaded. But in the End script block, I delete it.<\/p>\n<p><code lang=\"PowerShell\"><br \/>\nif (Test-Path $tmpfile) {<br \/>\n      Write-Verbose \"Deleting $tmpfile\"<br \/>\n      Remove-Item -Path $tmpFile<br \/>\n   }<br \/>\n<\/code><\/p>\n<p>The next time I run the function, I recreate the format file. But Update-FormatData also looks for the previous temp files which have since been deleted, which normally raises an exception. I'm not saying this approach of \"on the fly formatting\" is perfect but so far it works for me in these situations. The formatting file takes my custom object and creates a table with all properties except the access rules.<\/p>\n<p><a href=\"http:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/06\/get-aclinfo-1.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/06\/get-aclinfo-1-300x77.png\" alt=\"\" title=\"get-aclinfo-1\" width=\"300\" height=\"77\" class=\"aligncenter size-medium wp-image-2392\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/06\/get-aclinfo-1-300x77.png 300w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/06\/get-aclinfo-1-1024x264.png 1024w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/06\/get-aclinfo-1.png 1137w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>My format file allows for plenty of space for the file path. But you can always tighten things up.<\/p>\n<p><a href=\"http:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/06\/get-aclinfo-2.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/06\/get-aclinfo-2-300x77.png\" alt=\"\" title=\"get-aclinfo-2\" width=\"300\" height=\"77\" class=\"aligncenter size-medium wp-image-2393\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/06\/get-aclinfo-2-300x77.png 300w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/06\/get-aclinfo-2-1024x264.png 1024w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/06\/get-aclinfo-2.png 1137w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>If I want to work with the underlying access rules, I still can.<\/p>\n<p><a href=\"http:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/06\/get-aclinfo-3.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/06\/get-aclinfo-3-300x153.png\" alt=\"\" title=\"get-aclinfo-3\" width=\"300\" height=\"153\" class=\"aligncenter size-medium wp-image-2394\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/06\/get-aclinfo-3-300x153.png 300w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/06\/get-aclinfo-3-1024x524.png 1024w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/06\/get-aclinfo-3.png 1137w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Download <a href='http:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/06\/Get-ACLInfo.txt' target='_blank'>Get-ACLInfo<\/a> and let me know what you think.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I got a question in the &#8220;Ask Don and Jeff&#8221; forum on PowerShell.com that intrigued me. The issue was working with the results of the Get-ACL cmdlet. The resulting object includes a property called Access which is a collection of access rule objects. Assuming you are using this with the file system, these are System.Security.AccessControl.FileSystemAccessRule&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[4,8],"tags":[293,534,540,391],"class_list":["post-2390","post","type-post","status-publish","format-standard","hentry","category-powershell","category-scripting","tag-get-acl","tag-powershell","tag-scripting","tag-update-formatdata"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Get ACL Information with PowerShell &#8226; The Lonely Administrator<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/jdhitsolutions.com\/blog\/powershell\/2390\/get-acl-information-with-powershell\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Get ACL Information with PowerShell &#8226; The Lonely Administrator\" \/>\n<meta property=\"og:description\" content=\"I got a question in the &quot;Ask Don and Jeff&quot; forum on PowerShell.com that intrigued me. The issue was working with the results of the Get-ACL cmdlet. The resulting object includes a property called Access which is a collection of access rule objects. Assuming you are using this with the file system, these are System.Security.AccessControl.FileSystemAccessRule...\" \/>\n<meta property=\"og:url\" content=\"https:\/\/jdhitsolutions.com\/blog\/powershell\/2390\/get-acl-information-with-powershell\/\" \/>\n<meta property=\"og:site_name\" content=\"The Lonely Administrator\" \/>\n<meta property=\"article:published_time\" content=\"2012-06-21T15:09:55+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2012-06-21T15:17:05+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/06\/get-aclinfo-1-300x77.png\" \/>\n<meta name=\"author\" content=\"Jeffery Hicks\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@JeffHicks\" \/>\n<meta name=\"twitter:site\" content=\"@JeffHicks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jeffery Hicks\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/2390\\\/get-acl-information-with-powershell\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/2390\\\/get-acl-information-with-powershell\\\/\"},\"author\":{\"name\":\"Jeffery Hicks\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\"},\"headline\":\"Get ACL Information with PowerShell\",\"datePublished\":\"2012-06-21T15:09:55+00:00\",\"dateModified\":\"2012-06-21T15:17:05+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/2390\\\/get-acl-information-with-powershell\\\/\"},\"wordCount\":749,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\"},\"image\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/2390\\\/get-acl-information-with-powershell\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2012\\\/06\\\/get-aclinfo-1-300x77.png\",\"keywords\":[\"Get-ACL\",\"PowerShell\",\"Scripting\",\"Update-FormatData\"],\"articleSection\":[\"PowerShell\",\"Scripting\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/2390\\\/get-acl-information-with-powershell\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/2390\\\/get-acl-information-with-powershell\\\/\",\"url\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/2390\\\/get-acl-information-with-powershell\\\/\",\"name\":\"Get ACL Information with PowerShell &#8226; The Lonely Administrator\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/2390\\\/get-acl-information-with-powershell\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/2390\\\/get-acl-information-with-powershell\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2012\\\/06\\\/get-aclinfo-1-300x77.png\",\"datePublished\":\"2012-06-21T15:09:55+00:00\",\"dateModified\":\"2012-06-21T15:17:05+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/2390\\\/get-acl-information-with-powershell\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/2390\\\/get-acl-information-with-powershell\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/2390\\\/get-acl-information-with-powershell\\\/#primaryimage\",\"url\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2012\\\/06\\\/get-aclinfo-1.png\",\"contentUrl\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2012\\\/06\\\/get-aclinfo-1.png\",\"width\":\"1137\",\"height\":\"294\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/2390\\\/get-acl-information-with-powershell\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"PowerShell\",\"item\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/category\\\/powershell\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Get ACL Information with PowerShell\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/\",\"name\":\"The Lonely Administrator\",\"description\":\"Practical Advice for the Automating IT Pro\",\"publisher\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\",\"name\":\"Jeffery Hicks\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\",\"caption\":\"Jeffery Hicks\"},\"logo\":{\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Get ACL Information with PowerShell &#8226; The Lonely Administrator","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/jdhitsolutions.com\/blog\/powershell\/2390\/get-acl-information-with-powershell\/","og_locale":"en_US","og_type":"article","og_title":"Get ACL Information with PowerShell &#8226; The Lonely Administrator","og_description":"I got a question in the \"Ask Don and Jeff\" forum on PowerShell.com that intrigued me. The issue was working with the results of the Get-ACL cmdlet. The resulting object includes a property called Access which is a collection of access rule objects. Assuming you are using this with the file system, these are System.Security.AccessControl.FileSystemAccessRule...","og_url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/2390\/get-acl-information-with-powershell\/","og_site_name":"The Lonely Administrator","article_published_time":"2012-06-21T15:09:55+00:00","article_modified_time":"2012-06-21T15:17:05+00:00","og_image":[{"url":"http:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/06\/get-aclinfo-1-300x77.png","type":"","width":"","height":""}],"author":"Jeffery Hicks","twitter_card":"summary_large_image","twitter_creator":"@JeffHicks","twitter_site":"@JeffHicks","twitter_misc":{"Written by":"Jeffery Hicks","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/2390\/get-acl-information-with-powershell\/#article","isPartOf":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/2390\/get-acl-information-with-powershell\/"},"author":{"name":"Jeffery Hicks","@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9"},"headline":"Get ACL Information with PowerShell","datePublished":"2012-06-21T15:09:55+00:00","dateModified":"2012-06-21T15:17:05+00:00","mainEntityOfPage":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/2390\/get-acl-information-with-powershell\/"},"wordCount":749,"commentCount":1,"publisher":{"@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9"},"image":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/2390\/get-acl-information-with-powershell\/#primaryimage"},"thumbnailUrl":"http:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/06\/get-aclinfo-1-300x77.png","keywords":["Get-ACL","PowerShell","Scripting","Update-FormatData"],"articleSection":["PowerShell","Scripting"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/jdhitsolutions.com\/blog\/powershell\/2390\/get-acl-information-with-powershell\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/2390\/get-acl-information-with-powershell\/","url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/2390\/get-acl-information-with-powershell\/","name":"Get ACL Information with PowerShell &#8226; The Lonely Administrator","isPartOf":{"@id":"https:\/\/jdhitsolutions.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/2390\/get-acl-information-with-powershell\/#primaryimage"},"image":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/2390\/get-acl-information-with-powershell\/#primaryimage"},"thumbnailUrl":"http:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/06\/get-aclinfo-1-300x77.png","datePublished":"2012-06-21T15:09:55+00:00","dateModified":"2012-06-21T15:17:05+00:00","breadcrumb":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/2390\/get-acl-information-with-powershell\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/jdhitsolutions.com\/blog\/powershell\/2390\/get-acl-information-with-powershell\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/2390\/get-acl-information-with-powershell\/#primaryimage","url":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/06\/get-aclinfo-1.png","contentUrl":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/06\/get-aclinfo-1.png","width":"1137","height":"294"},{"@type":"BreadcrumbList","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/2390\/get-acl-information-with-powershell\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"PowerShell","item":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},{"@type":"ListItem","position":2,"name":"Get ACL Information with PowerShell"}]},{"@type":"WebSite","@id":"https:\/\/jdhitsolutions.com\/blog\/#website","url":"https:\/\/jdhitsolutions.com\/blog\/","name":"The Lonely Administrator","description":"Practical Advice for the Automating IT Pro","publisher":{"@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/jdhitsolutions.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9","name":"Jeffery Hicks","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg","url":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg","caption":"Jeffery Hicks"},"logo":{"@id":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg"}}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":2403,"url":"https:\/\/jdhitsolutions.com\/blog\/scripting\/2403\/working-with-access-rules-in-powershell\/","url_meta":{"origin":2390,"position":0},"title":"Working with Access Rules in PowerShell","author":"Jeffery Hicks","date":"June 22, 2012","format":false,"excerpt":"Yesterday I posted a function to create a summary report of ACL information using Windows PowerShell. I posted this in response to a question in the Ask Don and Jeff forum at PowerShell.com. I received an appreciative followup. The next step for this IT Pro it seems is to get\u2026","rel":"","context":"In &quot;Scripting&quot;","block_context":{"text":"Scripting","link":"https:\/\/jdhitsolutions.com\/blog\/category\/scripting\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1492,"url":"https:\/\/jdhitsolutions.com\/blog\/scripting\/1492\/creating-acl-reports\/","url_meta":{"origin":2390,"position":1},"title":"Creating ACL Reports","author":"Jeffery Hicks","date":"June 2, 2011","format":false,"excerpt":"I saw a tweet this morning that was a PowerShell one-liner for capturing folder permissions to a text file. There's nothing wrong with it but it's hard to be truly productive in 140 characters so I thought I would take the idea and run with it a little bit. Here\u2026","rel":"","context":"In &quot;Best Practices&quot;","block_context":{"text":"Best Practices","link":"https:\/\/jdhitsolutions.com\/blog\/category\/best-practices\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":3546,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell-3-0\/3546\/turn-on-powershell-help-window\/","url_meta":{"origin":2390,"position":2},"title":"Turn On PowerShell Help Window","author":"Jeffery Hicks","date":"November 7, 2013","format":false,"excerpt":"Here's a little suggestion for today that might make it easier for you to use PowerShell. In PowerShell 3.0, the Get-Help cmdlet includes a terrific new parameter called -ShowWindow. When you ask for help with this parameter, you get complete help in a new window. The window is re-sizable, searchable\u2026","rel":"","context":"In &quot;Powershell 3.0&quot;","block_context":{"text":"Powershell 3.0","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell-3-0\/"},"img":{"alt_text":"talkbubble-v3","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/05\/talkbubble-v3-150x150.png?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":1625,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/1625\/get-process-owner\/","url_meta":{"origin":2390,"position":3},"title":"Get Process Owner","author":"Jeffery Hicks","date":"August 25, 2011","format":false,"excerpt":"I've been working on my second training course for Train Signal on managing Windows Server 2008 with Windows PowerShell, specifically the lesson on managing processes. I thought I'd share a little tidbit I worked out. In fact, I hope you'll stay tuned for other little goodies over the next several\u2026","rel":"","context":"In &quot;PowerShell&quot;","block_context":{"text":"PowerShell","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":6855,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell-7\/6855\/powershell-scripting-for-linux-is-still-about-the-objects\/","url_meta":{"origin":2390,"position":4},"title":"PowerShell Scripting for Linux is Still About the Objects","author":"Jeffery Hicks","date":"October 8, 2019","format":false,"excerpt":"I've been trying to increase my Linux skills, especially as I begin to write PowerShell scripts and tools that can work cross-platform. One very important concept I want to make sure you don't overlook is that even when scripting for non-Windows platforms, you must still be thinking about objects. The\u2026","rel":"","context":"In &quot;PowerShell 7&quot;","block_context":{"text":"PowerShell 7","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell-7\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1171,"url":"https:\/\/jdhitsolutions.com\/blog\/scripting\/1171\/powershell-deep-dive-formatting-and-extensions\/","url_meta":{"origin":2390,"position":5},"title":"PowerShell Deep Dive Formatting and Extensions","author":"Jeffery Hicks","date":"February 25, 2011","format":false,"excerpt":"I just found out I will be presenting at the PowerShell Deep Dive April 18-19 that is part of TEC 2011. This promises to be THE PowerShell event everyone has been waiting for. I'll be presenting on format and type extensions. Mastering Format and Type Extensions Windows PowerShell is designed\u2026","rel":"","context":"In &quot;Conferences&quot;","block_context":{"text":"Conferences","link":"https:\/\/jdhitsolutions.com\/blog\/category\/conferences\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/2390","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/comments?post=2390"}],"version-history":[{"count":0,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/2390\/revisions"}],"wp:attachment":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/media?parent=2390"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/categories?post=2390"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/tags?post=2390"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}