powershell active directory picker - powershell

Actually i have a powershell script which analyzes the ntfs permissions on a file server. i enter the group name, specify the folder and afterwards i get the list. now i want to implement a active directory picker dialog like this instead of typing the group name
is there any powershell code to add to my script? this is what i have.
$gruppe = read-Host "group name"
Function Get-Folder($initialDirectory)
{
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")|Out-Null
$Ordnername = New-Object System.Windows.Forms.FolderBrowserDialog
$Ordnername.Description = "Ordner auswählen"
$Ordnername.rootfolder = "MyComputer"
if($Ordnername.ShowDialog() -eq "OK")
{
$Ordner += $Ordnername.SelectedPath
}
return $Ordner
}
$o = Get-Folder
write-host
function Get-FolderRightsForAccount([string]$dn, [string]$rootfolder, [switch]$includeInheritedRights){
$sids = #()
$sids += (Get-ADObject $dn -Properties objectSid).objectSid.Value
$sids += Get-ADPrincipalGroupMembership $dn | select -Expand GroupName
$inherited = #{$true=($true,$false);$false=$false}[$includeInheritedRights.IsPresent]
(Get-ACL $rootfolder).Access | ?{try{$_.IdentityReference.Translate([System.Security.Principal.SecurityIdentifier]).Value -in $sids -and $_.IsInherited -in $inherited}catch{}} | select #{n='Folder';e={$rootfolder}},AccessControlType,#{n='Rights';e={$_.FileSystemRights}}
gci $rootfolder -Recurse -Directory -PipelineVariable f | %{
(Get-ACL $_.Fullname).Access | ?{try{$_.IdentityReference.Translate([System.Security.Principal.SecurityIdentifier]).Value -in $sids -and $_.IsInherited -in $inherited}catch{}} | select #{n='Folder';e={$f.Fullname}},AccessControlType,#{n='Rights';e={$_.FileSystemRights}}
}
}
Get-FolderRightsForAccount -dn (Get-ADGroup $Gruppe).DistinguishedName -rootfolder $o -includeInheritedRights | ft -AutoSize

It's not a picker like shown, but could be even more useful. You can utilize the cmdlet Out-GridView. You can allow choosing many or limit to one item. You can filter and/or sort the list as well.
$selectedgroup = Get-ADGroup -Filter * |
Select-Object -Property Name, GroupCategory,GroupScope, SamAccountName,DistinguishedName |
Sort-Object -Property Name | Out-GridView -OutputMode Single -Title "Please choose a group"
if(!$selectedgroup){
Write-Host "No group was selected" -ForegroundColor Yellow
}

Related

PSCustomObject out-gridview incorrect formating

I am having an issue with the output from one property as a comma separated value instead of a list in the out-gridview. Is there a way to have a value be added to the output as a list instead of a single line?
.'C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1'
Connect-ExchangeServer -Auto -AllowClobber
do {
Write-Host
Write-Host
Write-Host
$name = Read-Host "What is the user's first name or letter?"
Write-Host
Write-Host
Write-Host
$list = Get-ADUser -Filter * | ? {$_.SamAccountName -match $name} |
select #{N="Highlight a User & Press Ctrl+C then Ctrl+V"; E={$_.SamAccountName}} |
sort SamAccountName |
Out-String
Write-Host -ForegroundColor Green $list
$box = Read-Host "Copy and paste the mailbox you want to see?"
$user = $box
$mailbox= Get-Mailbox -Identity $user | Get-MailboxStatistics |
Sort totalitemsize -desc |
select #{Name="User"; Expression={$_.DisplayName}},
#{Expression={"{0:N2}" -f($_.TotalItemSize.Value.ToMb()/1024)};label=”Mailbox Size in GB”},
#{Expression={"{0:N0}" -f($_.TotalItemSize.Value.ToMb())};label=”Mailbox Size in MB”},
#{Name="Message Count"; Expression={"{0:N0}" -f($_.itemcount)}},
#{Name="Database"; Expression={$_.DatabaseName}}
$folders= Get-MailboxFolderStatistics $user |
? {$_.ItemsInFolder -gt 0} |
Sort ItemsInFolder -Descending |
Select Name,
#{N="Items in Folder"; E={"{0:N0}" -f($_.ItemsInFolder)}},
#{N=”Folder Size in MB”;E={"{0:N0}" -f($_.FolderSize.ToMb())}}
$object= [PSCustomObject]#{
User = $mailbox.'User'
'Mailbox Size in MB'= $mailbox.'Mailbox Size in MB'
'Message Count' = $mailbox.'Message Count'
Database = $mailbox.Database
Name = $folders.Name
}
$object | Out-GridView
Write-Host
Write-Host
Write-Host
$runagain = Read-Host "Would you like to get another user's folder size?" | Out-String
Write-Host
Write-Host
}
while($runagain -like "y*")
Any help to get the $folders.Name to show as a list within the same out-Gridview would be great.
Thank you
You're probably looking for:
Name = $($folders.Name -join [Environment]::Newline)
This way you are not using an object anymore but are manually creating a list by joining the elements with a new line.

Delete the ":" character from results

I'm trying to list only unique HomeDrive for all users in a Universal Security group and remove nested groups errors.
Thanks for your help.
Denis
I've tried .TrimEnd(':'), can't seem to figure out where to put it
$Group = "Universal Security group"
$HomeDrive = Get-ADGroupMember $Group | `
ForEach-Object {
$UserName = $_.Name
Try {
#$ErrorActionPreference = "Stop"
Get-ADUser $UserName -Properties HomeDrive | Select HomeDrive
}
Catch {
Write-Host "Found a nested Group."
}
} | Sort-Object -Property 'HomeDrive' -Unique | Format-Table -HideTableHeaders | Out-String
Write-Host "$HomeDrive" -BackgroundColor DarkRed
The script does work but some users have their homedrives listed as only F while most are listed as F:. Basically making a lot of double entries and I do want the output to be only F. Also it generates 7 spaces after the :, That's why I have the background color.
Something like this:
$group = "Universal Security group"
$homeDrives = Get-ADGroupMember $Group |
ForEach-Object {
if ($_.ObjectClass -eq "User")
{
$user = Get-ADUser $_.Name -Properties "HomeDrive"
$homeDrive = $user.HomeDrive.Trim().TrimEnd(":")
return $homeDrive
}
} | Sort-Object -Unique
foreach ($homeDrive in $homeDrives)
{
Write-Host "Found home drive: $homeDrive" -BackgroundColor DarkRed
}

PowerShell Get-ACL with SamAccountName values

I'm trying to collect folder permissions to a csv file with Powershell. My problem is that I'd need the results to contain both the SamAccountName and FileSystemRights.
I tried two different method. The first I came up with was a simple approach that gave me IdentityReference and FileSystemRights, but I couldn't find any working method that can get SamAccountName from IdentityReference.
The second one I found on the internet was much more sophisticated. It collects all the accounts that has access to the folder, but it doesn't show FileSystemRights and I couldn't figure out how to change it to do so.
My own solution
(Get-Acl "FolderPath").Access | Select-Object IdentityReference, FileSystemRights
The solution I found
Get-Acl $UncPath | Select-Object -ExpandProperty Access | Where-Object { (-not $_.IsInherited) -and ('NT AUTHORITY\SYSTEM','BUILTIN\Administrators','CREATOR OWNER' -notcontains $_.IdentityReference) } | Select-Object -ExpandProperty IdentityReference | ForEach-Object { $_.Translate('System.Security.Principal.SecurityIdentifier').Value } | Get-ADGroup -ErrorAction SilentlyContinue | get-adgroupmember | select-object SamAccountName | Format-Table | Out-String
Is there any working method that can get me a result where I can see SamAccountName and FileSystemRights?
Thank you in advance.
$UncPath = 'E:\temp\test'
$all = Get-Acl $UncPath |
Select -ExpandProperty Access |
Where-Object { (-not $_.IsInherited) -and ('NT AUTHORITY\SYSTEM','BUILTIN\Administrators','CREATOR OWNER' -notcontains $_.IdentityReference) } |
Select-Object #{ Name = 'Identity'; Expression = { $_.IdentityReference -replace "\w+\\(.+)", '$1' } }, FileSystemRights
# Here you can get Users ACL
$distinct_users = $all |
Select-Object Identity, #{ Name = 'sAMAccountName'; Expression = { (Get-ADUser -Identity $_.Identity -ErrorAction SilentlyContinue).sAMAccountName }}, FileSystemRights |
Where-Object sAMAccountName -ne $null
# Here we will expand group acls
$groups = $all |
Select-Object Identity, #{ Name = 'sAMAccountName'; Expression = { (Get-ADGroup -Identity $_.Identity -ErrorAction SilentlyContinue).sAMAccountName }}, FileSystemRights |
Where-Object sAMAccountName -ne $null
# now we will get groups membership
$group_users = #()
Foreach($group in $groups){
Get-ADGroupMember -Identity $group.Identity | ForEach-Object { $group_users += [PSCustomObject]#{
'Identity' = $group.Identity
'sAMAccountName' = $_.sAMAccountName
'FileSystemRights' = $group.FileSystemRights
} }
}
$everyone = $distinct_users + $group_users
$everyone | Export-Csv -Path D:\example.csv
Check $everyone variable it will contain 3 columns: Identity as it was in the ACL, sAMAccountName and FileSystem Rights.

How to save Active Directory list of all users in all e-mail distributions to .CSV?

I found this example but I am not sure how I can properly save the output to a .csv.
Import-Module ActiveDirectory
$Groups = Get-ADGroup -Filter {GroupCategory -eq "Distribution"} -Properties Members
ForEach ($g in $Groups) {
Write-Host $g.name
Write-Host $g.members `n
}
I have tried something such as:
Import-Module ActiveDirectory
$Groups = Get-ADGroup -Filter {GroupCategory -eq "Distribution"} -Properties Members
ForEach ($g in $Groups) {
$g.name | Export-CSV C:\log.csv -notypeinformation -Append
$g.members | Export-CSV C:\log.csv -notypeinformation -Append
}
It only saves 1 column to the CSV which is called length.
This also makes me remove the 'n at the end of Write-Host $g.members `n
Is there a way that I can grab this data and save it to .csv properly?
UPDATE
With help from TheMadTechnician and this link https://blogs.technet.microsoft.com/heyscriptingguy/2013/07/22/export-user-names-and-proxy-addresses-to-csv-file/ I was able to get closer to what I want.
Import-Module ActiveDirectory
$Groups = Get-ADGroup -Filter {GroupCategory -eq "Distribution"} -Properties Members
ForEach ($g in $Groups) {
$g.name | Export-CSV C:\log.csv -notypeinformation -Append
$g.members | Export-CSV C:\log.csv -notypeinformation -Append
}
$Groups | Select Name,#{L='Members_1'; E={$_.members[0]}}, #{L='Members_2';E={$_.Members[1]}}, #{L='Members_3';E={$_.Members[2]}}, #{L='Members_4';E={$_.Members[3gq]}} | Export-Csv C:\log.csv -notype
This gives me an output of the below in my CSV:
Name Members_1 Members_2 ETC...
NameOfGroup CN=Stormy Daniels,OU=IT,DC=DomainName,DC=com CN=Joe Bob,OU=IT,DC=DomainName,DC=com
Now the list of users can be huge so I would have to continue creating Members_3, Members_4, etc...
I'm not sure if there is a way I can specify all users or loop
#{L='Members_1'; E={$_.members[0]}}
and increment the number until all users are displayed.
I also only need the CN with the name. I don't need the Ou= or Dc=.
Ah this proved harder than I expected - due to the member counting (you have to do a count which can be comparable to integer). I have added a possibility to limit result size as for large queries the active directory produces timeouts.
$limit_result_size = 10
$group_name = Get-ADGroup -Filter {GroupCategory -eq "Distribution"} -Properties Name, Members -ResultSetSize:$limit_result_size | Select-object name
ForEach ($name in $group_name.name) {
If ((![String]::IsNullOrEmpty("$name")) -And ("$name" -notlike 'index')) {
$count_members = Get-ADGroupMember -Identity "$name" | Measure-Object | Select-Object Count
Write-Output "The AD group $name has $($count_members.Count) members.`n"
For($counter = 0; $counter -lt $count_members.Count; $counter++) {
$person = Get-ADGroup -Filter {Name -eq $name} -Properties Name, Members | Select-Object Name, #{N='Members';E={$_.Members[$counter]}}
$person.Members = $person.Members | Select-String 'CN=[0-9a-zA-Z]+' -AllMatches | % { $_.Matches } | % { $_.Value }
$person | export-csv -NoTypeInformation -Append -Path '<your_path>\log.csv'
}
}
}
Short description:
(![String]::IsNullOrEmpty("$name")) -And ("$name" -notlike 'index')) conditions which the AD group should satisfy.
Select-String 'CN=[0-9a-zA-Z]+' -AllMatches | % { $_.Matches } | % { $_.Value } Selects only CN=string_with_numbers. You could replace it with CN=\w+ if you prefer.
The script produces a pair in CV AD group and the CN=user_name. If anything else is unclear please ask.
EDIT
If you have spaces in the names of the Common Names (CN) you have to adjust the regexp to CN=[0-9a-zA-Z\s]+.
EDIT 2 Adding user's email addresses.
Since your question has in the title request for emails I'll answer here without new question. Note that this solution uses lookbehind in regexp to exclude the CN= from the output so it can be used as source for the user query. It also uses a PSCustomObject which gathers all the information together. I have renamed some variables to make better sense in the context of user details.
$limit_result_size = 10
$group_name = Get-ADGroup -Filter {GroupCategory -eq "Distribution"} -Properties Name, Members -ResultSetSize:$limit_result_size | Select-object name
ForEach ($name in $group_name.name) {
If ((![String]::IsNullOrEmpty("$name")) -And ("$name" -notlike 'index')) {
$count_members = Get-ADGroupMember -Identity "$name" | Measure-Object | Select-Object Count
Write-Output "The AD group $name has $($count_members.Count) members.`n"
For($counter = 0; $counter -lt $count_members.Count; $counter++) {
$person = Get-ADGroup -Filter {Name -eq $name} -Properties Name, Members | Select-Object Name, #{N='Members';E={$_.Members[$counter]}}
$person.Members = $person.Members | Select-String '(?<=CN=)[0-9a-zA-Z\s]+' -AllMatches | % { $_.Matches } | % { $_.Value }
$person_details = Get-AdUser -filter {name -eq $member} -Properties mail | Select-Object mail
$person_additional_details = [PSCustomObject]#{ group_name = $group.Name
user_name = $group.Members
email = $person_details.mail
}
If ([String]::IsNullOrEmpty($($person_additional_details.email))) {
$person_additional_details.psobject.properties["email"].value = '<empty>'
}
# For user to see the written data
Write-Output "AD Group: $($person_additional_details.group_name) `
AD User: $($person_additional_details.user_name) `
Users`'s email: $($person_additional_details.email)`n"
# writing into the CSV file
$person_additional_details | export-csv -NoTypeInformation -Append -Path '<your_path>\log.csv'
}
}
}

Powershell script to audit new AD accounts & groups

I am trying to create a powershell to audit new created accounts & groups and who created them. The objects are created by account operators, but they are not domain admins.
I think something like this:
$Last = (Get-Date).AddDays(-1);
Get-Acl | Get-ADUser -Filter {WhenCreated -ge $Last} | FL DistinguishedName, Path,owner
But this doesn't work yet.
This one liner will let you know about the changes after a certain date. There is a whenchanged property with which you can filter down the objects.
Get-ADObject -Filter 'whenchanged -gt $dte' | Group-Object objectclass
then you can use :
get-adgroup -filter * | sort name | select Name
Get-adgroupmember "Name"
or
Get-ADGroup -filter "GroupCategory -eq 'Security'" –properties Member |
Select Name,#{Name="Members";
Expression={($_.member | Measure-Object).count}},
GroupCategory,GroupScope,Distinguishedname |
Out-GridView -Title "Select one or more groups to export" -OutputMode Multiple |
foreach {
Write-Host "Exporting $($_.name)" -ForegroundColor cyan
#replace spaces in name with a dash
$name = $_.name -replace " ","-"
$file = Join-Path -path "C:\work" -ChildPath "$name.csv"
Get-ADGroupMember -identity $_.distinguishedname -Recursive |
Get-ADUser -Properties Title,Department |
Select Name,Title,Department,SamAccountName,DistinguishedName |
Export-CSV -Path $file -NoTypeInformation
Get-Item -Path $file
}