Powershell export ACL permissions to CSV - powershell

I am still on the learning curve with powershell, i currently have the following script:
$users = Get-Acl $Path |
Select-Object -ExpandProperty access |
ft identityreference |
where { $_.identityreference -like "UK\"}
$Path is the location of a particular share on a server. I currently have a CSV file called "test" with about 100 share names on the same server (The first column heading named "ShareNames"), the second column is named "GroupName".
I need to update this script to search through the first column in the CSV file called "test.csv" and push out the appropriate group permission to that share in the second column. I have to also admit the last part of the script does not work :( i am having trouble filtering out a common group name we have as i do not want the whole list of groups for every share only group names that start with ("uk\gro...").
Thank you for any guidance / help

I would choose -match over -like and skip the Format-Table. The following would filter the ACEs on their property IdentityReference using the regex ^UK\\ -- I am assuming that 'UK\' is the domain portion of the group name within the ACEs:
$user = Get-Acl $path |
Select-Object -ExpandProperty access |
Where-Object { $_.IdentityReference -match '^UK\\' }
Then you can ft as desired:
$user | Format-Table
If you need to feed in a CSV of paths, you can pipe an Import-Csv into a ForEach-Object wrapped around the above example.
Import-Csv test.csv |
ForEach-Object {
Write-Output "ACEs on $($_.ShareNames) matching 'UK\'"
Get-Acl $_.ShareNames |
Select-Object -ExpandProperty access |
Where-Object { $_.IdentityReference -match '^UK\\' }
}
I'm still not clear on how you intend to populate the "GroupName" column in the output as there could be multiple entries for groups beginning with 'UK\'.

Related

Powershell - parse from CSV Second Column "Owners" and keep output of failures

I'm trying to get a list of AD Group owners from a CSV file, the second column is what I want to pull from, it is titled Owners I want to keep the output if there are failures as well. Would I just modify the "foreach" portion of my code?
Get-Content "C:\tmp\SMB.csv" -OutVariable | foreach {
Get-ADGroup -identity $_ -properties name,managedby| select name,managedby |
out-file c:\temp\test.csv -Append }
To get the owners values just use
Get-Content 'C:\tmp\SMB.csv' | ConvertFrom-Csv | Select Owners

Excluding folders using Get-ChildItem -Exclude

I require to exclude user profiles from \\Computer\c$\Users folder when using Get-ChildItem.
I potentially need to exclude 100 profiles from various machines so have created a variable that contains all user profiles from an AD security group that I want excluding but when I run the below command it doesn't work but if I list the profiles in plain text it does work.
Get-ChildItem "\\$computer\c$\Users" -Exclude $ListOfUsers
But works if I run Get-ChildItem "\\$computer\c$\Users" -Exclude Bob1,Bob2,Bob3,Bob4,Bob5
My code to obtain the users from AD security groups are below and the format it outputs to is like the above with commas.
## collects users from groups and adds to exlusion list.
$1stline = Get-ADGroupMember GG_1st_Line_Team | Select SamAccountName
$2ndline = Get-ADGroupMember GG_2nd_Line_Team | Select SamAccountName
$3rdline = Get-ADGroupMember GG_3rd_Line_Team | Select SamAccountName
$FieldTech = Get-ADGroupMember "Field tech" | select SamAccountname
$Excluded = $1stline + $2ndline + $3rdline + $Fieldtech | Out-File "C:\temp\Members.txt"
(get-content c:\temp\Members.txt) -join "," | out-file C:\temp\Format.txt
$format = get-content c:\temp\format.txt; $format = $format -replace '\s',''; $format = $format -replace ',SamAccountName,--------------,',''; $format = $format.trimend(",,") | Out-File "C:\temp\newFormat.txt"
$excluded = Get-Content C:\Temp\newFormat.txt
This will create a text file with 100 names with no spaces, only commas to seperate the users. If I Write-Host the variable $newformat the commas are White along with the text but if I put the Profile names in plain text then the commas are grey...
The excessive use of Out-File is unnecessary and will cause you issues as it changes objects into strings. You then have to use commands like Split and Join to turn the strings back into the object (arrays here) you require.
Out-File should only be used when you actually need the output as a file.
With a few simple changes to your script it'll do what you want, and be a lot simpler too!
You can use ExpandProperty to only return the value of SamAccountName itself as a string rather than an object.
You can then simply create an array of those strings and use this to exclude those accounts/folders from Get-ChildItem,
$1stline = Get-ADGroupMember GG_1st_Line_Team | Select-Object -ExpandProperty SamAccountName
$2ndline = Get-ADGroupMember GG_2nd_Line_Team | Select-Object -ExpandProperty SamAccountName
$3rdline = Get-ADGroupMember GG_3rd_Line_Team | Select-Object -ExpandProperty SamAccountName
$FieldTech = Get-ADGroupMember "Field tech" | Select-Object -ExpandProperty SamAccountname
$excluded = $1stline,$2ndline,$3rdline,$Fieldtech
Get-ChildItem "\\$computer\c$\Users" -Exclude $excluded
You could then look into using a foreach loop with Get-ADGroupMember to cut down on the duplicated Get-ADGroupMember code.
The problem here seems to be that you're using a [string] variable with a value of Tom,Dick,Harry.
I bet you've got no folders like this, have you?
Whilst you can pass a [string] in to the -Exclude parameter; that will be a singleton (a single, scalar value); and the best you'll get is a single exclusion.
What you really want to pass in is a string array: [string[]]!
[string]$excludedString = "Tom,Dick,Harry"
[string[]]$excludedArray = $excludedString -split ","
Get-ChildItem -Path "C:\users" -Exclude $excludedArray

Check AD Computer Names against CSV file

I'm trying to write a Powershell script that will import a list of computer names from a CSV file and compare it against all computer names in AD. I need it to output a list of names from the CSV file that do not exist in AD.
I have been playing around with these commands but they don't do exactly what I want.
$import = Import-Csv -Path C:\Users\username\Desktop\test.csv
$AD-Names = Get-ADComputer -filter * | Select -Expand Name
Compare-Object $import $AD-Names
This seems to give me a list of everything different from both variables which is an extremely long list. I really just need to know which computer names in the CSV file are not in AD.
Simply compare the names from your CSV against the list of names from AD (I'm going to assume that the column title of the CSV is Name):
$ADNames = Get-ADComputer -Filter * | Select-Object -Expand Name
Import-Csv 'C:\path\to\input.csv' |
Where-Object { $ADNames -notcontains $_.Name } |
Export-Csv 'C:\path\to\not_in_AD.csv' -NoType
Side note: $AD-Names is not a valid variable name. Change the hyphen to an underscore or remove it entirely, or put the variable name in curly brackets (${AD-Names}).
First, why do you need a csv file if there are only computer names ?
CSV files are usually used to store a table in a simple text file.
If your CSV only contains the computer names, and you only want to check for computer names, this could work for you :
$OutputComputers = #();
$InputComputers = Import-Csv input.csv -Header ComputerName;
$AdComputers = Get-ADComputer -Filter 'Name -like "*"';
$InputComputers | ForEach-Object {$i = 0} {
if ($_.ComputerName -notin $AdComputers.Name) {
$OutputComputers += New-Object PsObject -property #{
'ComputerName' = $_.ComputerName
}
}
}
$OutputComputers | Export-Csv output.csv -Delimiter ";" -Encoding UTF8 -Force -NoTypeInformation
Hope it helps.

PowerShell foreach loop export to new column in CSV format

I am currently working with a CSV file that has a manager's employee number, but not their SAMAccountName. I want to utilize Get-ADUser to grab the manager's SAMAccountName from their EmployeeNumber attribute and place that inside a new column in the same CSV file.
CSV sample:
"Full Name","Username","Manager","Manager User Sys ID"
"User 1","u1","1, Manager","123456"
"User 2","u2","2, Manager","234567"
"User 3","u3","3, Manager","345678"
I would like:
"Full Name","Username","Manager","Manager User Sys ID","Manager SamAccountName"
"User 1","u1","1, Manager","123456","m1"
"User 2","u2","2, Manager","234567","m2"
"User 3","u3","3, Manager","345678","m3"
I have spent some time putting together the following code. I can get a new column added and can further grab the SAMAccountName, but it only exports a single line in the new CSV file like this:
"SAMAccountName","managerUsername"
"m1","#{SAMAccountName=m1}"
Here is the code:
$managers = Import-Csv -Path .\test.csv
$usermananger = #()
foreach ($manager in $managers)
{
$getmanagersam = Get-ADUser -Filter "employeeNumber -eq $($manager."Manager User Sys ID")" -Properties SAMAccountName |
Select-Object SAMAccountName
$exportstring = $testmanager |
Select-Object *,#{Name='managerUsername';Expression={"$getmanagersam"}}
$exportstring | Export-Csv -Path .\simpletest.csv -NoTypeInformation
}
As #MathiasR.Jessen mentioned in the comments: you need to expand the SamAccountName property to get just the value. Also, you're overwriting your output CSV with every iteration. Either append to the file, or move the Export-Csv cmdlet outside the loop. The former requires PowerShell v3 or newer, the latter requires that you change the loop to a ForEach-Object loop (or run the foreach loop in a subexpression).
Personally I'd prefer using a pipeline, so I'd pick the latter:
Import-Csv -Path .\test.csv | ForEach-Object {
$acct = Get-ADUser -Filter "employeeNumber -eq $($_.'Manager User Sys ID')" |
select -Expand SamAccountName
$_ | select *,#{Name='managerUsername';Expression={$acct}}
} | Export-Csv -Path .\simpletest.csv -NoTypeInformation
The short answer is to add the -Append option to your export-csv statement to stop it overwriting each time round the loop.
Alternatively move the export outside the loop as follows:
$managers = Import-Csv -Path .\test.csv
$managers|foreach-object{
$getmanagersam = Get-ADUser -Filter "employeeNumber -eq $($_.'Manager User Sys ID')" | select -ExpandProperty SAMAccountName
$_|Select *,#{Name='managerUsername';Expression=$getmanagersam}
} | Export-Csv -Path .\simpletest.csv -NoTypeInformation
Note: looks like #AnsgarWiechers beat me to it :-)
I'm late to the party it looks like, but that rarely stops me... I'm not a huge fan of adding properties via the Select cmdlet, so I'm going to offer an alternative where you pipe the CSV to a ForEach-Object loop (just like the other answers), but inside that you use Add-Member with the -PassThru argument, and then pipe it off to the output file. I will add a new line and indent after the pipes, just to make it easier to read.
Import-Csv -Path ".\test.csv" |
ForEach-Object {Add-Member -InputObject $_ -NotePropertyName 'managerUserName' -NotePropertyValue (Get-ADUser -Filter "employeeNumber -eq $($_.'Manager User Sys ID')").samaccountname -PassThru} |
Export-Csv -Path ".\simpletest.csv" -NoTypeInformation
This should essentially do the exact same thing as the other two answers, it just adds the property differently, because variety is the spice of life! (I saw that on the internet somewhere, so it must be true.)

Powershell output

Having trouble getting the output I want from some powershell commands. I'm creating a powershell script to help clean up home directories. I need to get the permissions of the directory and make sure that the name of the directoy and the user who has access match.
I'm using the Get-Acl function and it has alot of extra data. In theory the file permissions on these directories should have Administrators as the owner, the user should be the only person listed under Access.
PS C:\> Get-Acl "\\fs1\home\e55555"
Directory: \\fs1\home
Path Owner Access
---- ----- ------
e55555 BUILTIN\Administrators DOM\e55555 Allow ...
I would like to filter out everything except what is under access. I tried piping | select Access but it doesn't give me the same output.
I know I'll have extra information besides the UserID so I figured I could write to a file and try to "grep" what I needed. Through some googling and experimentation I got some output I felt would be easy to parse, here is the command and output:
PS C:\> $test = Get-Acl \\fs1\home\\e55555 | Select-Object -ExpandProperty Access
| select IdentityReference
IdentityReference
-----------------
DOM\e55555
NT AUTHORITY\SYSTEM
BUILTIN\Administrators
NT AUTHORITY\Authenticated Users
Tried to use regex to find the line I wanted, none of the things I tried gave me any output. I tried different variations of the commands below and also tried parsing a file instead of a variable:
echo $test | Select-String -pattern "^DOM"
[regex]::matches($test,"^DOM")
So how can I trim down my output on my get-acl command? And how can I "grep" for any lines starting with DOM without extra data?
This should give you the access-objects for all users in your domain
$path = "\\fs1\home\\e55555"
(Get-Acl $path).Access | where { $_.IdentityReference -like "DOM*"}
If you want to check that user is in there, you could use:
$path = "\\fs1\home\\e55555"
$username = $path | Split-Path -Leaf
(Get-Acl $path).Access | where { $_.IdentityReference -like "DOM\$username"}
I didn't extract the Identityreference property since you need the whole access object if you want to check the permissions. If you save the Get-Acl outputs to a variable (ex. $access = Get-Acl ......), you can check that the user had a access rule by using if($access) { do something }
EDIT: Just as an idea. If you only want the folders where a user with the same name as the folder doesn't have an access rule(without checking what kind of rights the user has), you could try:
$acls = Get-ChildItem "\\fs1\home\" | Get-Acl
foreach ($acl in $acls) {
$users = $acl.Access | select -ExpandProperty IdentityReference
$username = $acl.PSChildName
if ($users -notcontains "DOM\$username") { $username }
}
This should output an array of foldernames(ex. "e55555") where something IS wrong(ex. user "e55555" doesn't have any access to the folder "e55555").
I think you think-string all the time. Try to see objects instead. And to filter - use where, not select-string. E.g.:
$HomeDrive = '\\fs1\home\'
$User = 'e55555'
(Get-Acl $HomeDrive$User).Access |
where { $_.IdentityReference -match $user }
That should get you started...? :)
Try adding the -Expand to IdentityReference too. To build on what you were doing:
Get-Acl "\\fs1\home\\e55555" | Select-Object -ExpandProperty Access |
select -expand IdentityReference | ?{ $_.StartsWith("DOM") }
To make it simpler:
(Get-Acl "\\fs1\home\\e55555").Access | Select -Expand IdentityReference | ?{ $_.StartsWith("DOM") }