Powershell: Get Mailbox Permissions - only from ADUsers with a givenname + surname - powershell

I need to make a CSV file with the name of the mailbox (mb Identity), user, accessrights and deny. But I only want to that for ADUsers who have a givenname AND a surname not only a surname.
I thought of something like that:
$File_Path = $args[0]
$File_Path = ((Get-Item -Path ".\" -Verbose).FullName) + "\" + $File_Path
$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding($False)
[System.IO.File]::WriteAllLines($File_Path, "Mailbox;RightHolder;Rights;Deny", $Utf8NoBomEncoding)
$Mailboxes = Get-Mailbox -ResultSize Unlimited
Foreach ($Mailbox in $Mailboxes) {
$mbPermissions = get-mailboxpermission $Mailbox
$str_DN = $Mailbox.DistinguishedName
$ad_obj = [ADSI]"GC://$str_DN"
Foreach ($mbPermission in $mbPermissions) {
If ($mbPermission.IsInherited -eq $False -and $mbPermission.User -notlike "NT-AUTORITÄT\SELBST") {
[System.IO.File]::AppendAllText($File_Path, "$($mbPermission.Identity);$($mbPermission.User);$($mbPermission.AccessRights);$($mbPermission.Deny)`r", $Utf8NoBomEncoding)
}
}
$ADPermissions = get-ADPermission $Mailbox.Identity
Foreach ($ADPermission in $ADPermissions) {
If ($ADPermission.ExtendedRights -like "Send-As" -and $ADPermission.User -notlike "NT-AUTORITÄT\SELBST" -and $ADPermission.Deny -eq $false) {
[System.IO.File]::AppendAllText($File_Path, "$($ADPermission.Identity);$($ADPermission.User);$($ADPermission.ExtendedRights);$($ADPermission.Deny)`r", $Utf8NoBomEncoding)
}
}
}
This works perfectly fine for creating the csv file with all credentials I need, but it doesn't exclude mailboxes from users who have no givenname. I'm a little bit stuck here.
Thanks for your help!
EDIT:
Solved it! Just put these lines instead of the $Mailboxes part:
$Mailboxes = get-mailbox -ResultSize Unlimited | select -ExpandProperty samaccountname
$Filter = foreach ($Obj in $Mailboxes) { get-aduser $Obj | select -property givenname,samaccountname }
$NoGivenName = $Filter | where { $_.givenname -ne $null } | select -ExpandProperty samaccountname
$BoxesFiltered = foreach ($Box in $NoGivenName) { get-mailbox $Box }

Can you try the following, it may take a little longer as the it has to filter out with a Get-ADUser to regenerate the list.
Import-Module ActiveDirectory
$File_Path = $args[0]
$File_Path = ((Get-Item -Path ".\" -Verbose).FullName) + "\" + $File_Path
$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding($False)
[System.IO.File]::WriteAllLines($File_Path, "Mailbox;RightHolder;Rights;Deny", $Utf8NoBomEncoding)
$Mailboxes = Get-Mailbox -ResultSize Unlimited
$Mailboxes = Foreach ($Mailbox in $Mailbox){ (get-aduser $mailbox | where { ([string]::IsNullOrEmpty($_.givenname) -eq $false) }).samaccountname }
Foreach ($Mailbox in $Mailboxes)
{
$mbPermissions = get-mailboxpermission $Mailbox
$str_DN = $Mailbox.DistinguishedName
$ad_obj = [ADSI]"GC://$str_DN"
Foreach ($mbPermission in $mbPermissions)
{
If ($mbPermission.IsInherited -eq $False -and $mbPermission.User -notlike "NT-AUTORITÄT\SELBST")
{
[System.IO.File]::AppendAllText($File_Path, "$($mbPermission.Identity);$($mbPermission.User);$($mbPermission.AccessRights);$($mbPermission.Deny)`r", $Utf8NoBomEncoding)
}
}
$ADPermissions = get-ADPermission $Mailbox.Identity
Foreach ($ADPermission in $ADPermissions)
{
If ($ADPermission.ExtendedRights -like "Send-As" -and $ADPermission.User -notlike "NT-AUTORITÄT\SELBST" -and $ADPermission.Deny -eq $false)
{
[System.IO.File]::AppendAllText($File_Path, "$($ADPermission.Identity);$($ADPermission.User);$($ADPermission.ExtendedRights);$($ADPermission.Deny)`r", $Utf8NoBomEncoding)
}
}
}

Related

Refresh a variable within a foreach statement

We have a master registry within our on premise SharePoint environment, to keep this list accurate, we run a clean up script each day to remove the item within the list registry.
As part of this script, we wish to delete the AD permissions group at the same time.
Our script works when deleting a single site collection, but when multiple are deleted, the script removes the list item, but attempts to delete the same AD group over and over, it doesnt refresh the variables.
Here is part of the script:
Add-PSSnapin *sharepoint* -ErrorAction SilentlyContinue
Import-Module ActiveDirectory
#Adding variables
$siteRequestUrl = "https://contorso/sites/demo"
$siteRequestListTitle = "Registry"
$webAppArray = #()
$listSCArray = #()
$itemsToDeleteArray = #()
$dn = Get-ADDoman | select -ExpandProperty DistinguishedName
$ou = Get-ADOrganizationalUnit ('Ou=SharePoint, OU=Account Groups, OU=Groups,' + $dn)
$ouSDL = Get-ADOrganizationalUnit ('Ou=SharePoint, OU=Resource Groups, OU=Groups,' + $dn)
Start-SPAssignment -Global
$list = (Get-SPSite -Identity $siteRequestUrl).RootWeb.Lists | Where-Object { $_.Title -eq $siteRequestListTitle }
$expectedSCCount = $list.ItemCount
$WebAppSCCount = $list.ParentWeb.Site.WebApplication.Sites
If ($expectedSCCount -ne $webAppSCCount) {
$listItems = $list.Items
foreach ($webAppSC in $list.ParentWeb.Site.WebApplication.Sites) {
$webAppSCArray += $webAppSC.Url
}
foreach ($item in $listItems) {
$li = New-Object Microsoft.SharePoint.SPFieldUrlValue($item["URL_Link"])
$listSCArray += $i.Url.String()
}
$comparison = Compare-Object -ReferenceObject $webAppSCArray -DifferenceObject $listSCArray | where-Object -FilterScript { $_.SiteIndicator -eq '=>' }
foreach ($difference in $comparison) {
foreach ($item in $listItems) {
$i = New-Object Microsoft.SharePoint.SPFieldUrlValue($item["URL_Link"])
If ($i.Url -eq $difference.InputObject) {
$itemsToDeleteArray = + $item
}
}
}
$itemTitle - $itemToDelete.Title.ToString()
$itemTemplate - $itemToDelete["Template"].ToString()
###### Now I move onto the problem, these variables work but do not not refresh if more than one item is being deleted ############
foreach ($itemToDelete in $itemToDeleteArray) {
switch ($itemTemplate) {
"Branch1" {
$managedPath = "BR1"
}
"Branch2" {
$managedPath = "BR2"
}
}
$forceLowerCase = $itemTitle.ToLower()
$siteTitle = $forceLowerCase -replace '\W', '-'
$GroupName = $managedPath + "-" + $siteTitle
$SggGroupName = "SGG_" + $GroupName + "_Members"
$SdlGroupName = "SDL_" + $GroupName + "_Members"
Try {
Get-ADGroup -Filter 'GroupCatergory -eq "Security" -and GroupScope -ne "DomainLocal"' -SearchBase "CN=$SggGroupName,OU=SharePoint,OU=Account Groups,OU=Groups,DC=Contorso" | Remove-ADGroup -Confirm:$false
Get-ADGroup -Filter 'GroupCatergory -eq "Security" -and GroupScope -eq "DomainLocal"' -SearchBase "CN=$SdlGroupName,OU=SharePoint,OU=Resource Groups,OU=Groups,DC=Contorso" | Remove-ADGroup -Confirm:$false
Write-host "AD Groups $SggGroupName and $SdlGroupName deleted" -ForegroundColor -Green
}
Catch { write-host "AD Groups $SggGroupName and $SdlGroupName failed to delete" }
$itemToDelete.Delete()
}
}
Stop-SPAssignment -Global

Powershell - cheking var is giving me the right results but Export-CSV gives numbers

what I want is that the $report_groups val gives me in Export-CSV the output that i get in Terminal. But i cant figure it why does he gives me Numbers.
$get_AD_Groups = Get-ADGroup -Filter '*' | Select-Object Name
$report_groups = New-Object -TypeName System.Collections.ArrayList
foreach ($item in $get_AD_Groups) {
$get_users = $item.Name | Get-ADGroupMember | Select-Object Name
$disabled_user = 0
foreach ($user in $get_users) {
$status = $user.Name | Get-ADUser -ErrorAction SilentlyContinue
if(($status.ObjectClass -eq 'user') -and ($status.Enabled -ne 'True')) {
$disabled_user++
}
}
if ($get_users.Count -eq $disabled_user) {
$report_groups.Add($item.Name)
}
}
$report_groups | Export-Csv -Path "..\report.csv" -NoTypeInformation -Force -Delimiter ";"
Now when i run $report_groups in Terminal i get the list of the AD Group BUT as soon i do the Export-CSV this is what i get:
So thanks again to Lee_Dailey for helping me on this.
Changes done.
$report_groups = #()
if ($get_users.Count -eq $disabled_user) {
$fill = [PSCustomObject]#{
AD_GROUP = $item.Name
}
$report_groups += $fill
}

Creating new PsObject

I must be doing something wrong here results are empty, I tried converting html with PsObject it requires -Append that creates multiple html tables and not suited to send an email, any help appreciated.
Foreach($sender in $senders){
$users=Get-TransportServer|Get-MessageTrackingLog -Start (Get-Date).AddHours(-4) -ResultSize Unlimited -Sender $sender.PrimarySmtpAddress |?{$_.Recipients -notlike "*#domain.us" -and $_.RecipientCount -eq "1" -and $_.RecipientStatus -notlike "*,*" -and $_.eventid -eq 'RECEIVE' }
}
$users | % {
$t = New-Object PSObject -Property #{
Sender = $_.Sender
Receiver = $_.Recipients
Messagesubject=$_.Messagesubject
RecipientCount =$_.RecipientCount
TimeStamp=$_.TimeStamp
}
$outtbl += $t
}
$outtbl
Why do you need $users, $outtbl, or $t?
foreach ( $sender in $senders ) {
Get-TransportServer |
Get-MessageTrackingLog -Start (Get-Date).AddHours(-4) -ResultSize Unlimited -Sender $sender.PrimarySmtpAddress |
Where-Object { ($_.Recipients -notlike "*#domain.us") -and
($_.RecipientCount -eq 1) -and
($_.RecipientStatus -notlike "*,*") -and
($_.eventid -eq 'RECEIVE') } | ForEach-Object {
[PSCustomObject] #{
Sender = $_.Sender
Receipients = $_.Recipients
MessageSubject = $_.MessageSubject
RecipientCount = $_.RecipientCount
TimeStamp = $_.TimeStamp
}
}
}
(Not tested - this is just an example of how to eliminate unnecessary variables and write clearer code.)
This code sample requires PowerShell 3.0 or newer because it uses [PSCustomObject].
This was it
foreach ( $sender in $senders ) {
Get-TransportServer |
Get-MessageTrackingLog -Start (Get-Date).AddHours(-4) -ResultSize Unlimited -Sender $sender.PrimarySmtpAddress |
Where-Object { ($_.Recipients -notlike "*#domain.us") -and
($_.RecipientCount -eq 1) -and
($_.RecipientStatus -notlike "*,*") -and
($_.eventid -eq 'RECEIVE') } | ForEach-Object {
$results += New-Object PSObject -Property #{
Sender = $_.Sender
Receiver = $_.Recipients
MessageSubject = $_.MessageSubject
RecipientCount = $_.RecipientCount
TimeStamp = $_.TimeStamp
}
}
}
$results| ConvertTo-Html -Head $style| Out-File $reportpath

Get all AD Users and their group memberships (recursively) using Powershell

I have a script from a previously answered question, but don't have enough reputation to comment. I tried to run that script and came across this error message:
Export-CSV : Cannot append CSV content to the following file: C:\users.csv. The appended object does not have a property that corresponds to the following column: User;Group. To continue with mismatched properties, add the -Force parameter, and then retry the command.
How can I debug this script to resolve this issue?
Function Get-ADGroupsRecursive{
Param([String[]]$Groups)
Begin{
$Results = #()
}
Process{
ForEach($Group in $Groups){
$Results+=$Group
ForEach($Object in (Get-ADGroupMember $Group|?{$_.objectClass -eq "Group"})){
$Results += Get-ADGroupsRecursive $Object
}
}
}
End{
$Results | Select -Unique
}}
import-module activedirectory
$users = get-aduser -Filter {Name -Like "*"} -Searchbase "OU=Sample Accounts,DC=domain,DC=com" -Properties MemberOf | Where-Object { $_.Enabled -eq 'True' }
$targetFile = "C:\users.csv"
rm $targetFile
Add-Content $targetFile "User;Group"
foreach ($user in $users)
{
$Groups = $User.MemberOf
$Groups += $Groups | %{Get-ADGroupsRecursive $_}
$Groups | %{New-Object PSObject -Property #{User=$User;Group=$_}}|Export-CSV $targetfile -notype -append
}
try this function
function Get-InChainGroups
{
param (
[parameter(mandatory = $true)]
$user,
$domain)
$user1 = (get-aduser -filter { name -eq $user } -server $domain).distinguishedname
Write-verbose "checking $user"
$ldap = "(&(objectcategory=group)(groupType:1.2.840.113556.1.4.803:=2147483648)(member:1.2.840.113556.1.4.1941:=$user1))"
try { Get-ADobject -LDAPFilter $ldap -server $domain | select #{ n = 'Identity'; e = { $user } }, Name, #{ n = 'DN'; e = { $_.distinguishedname } } | ft -a }
catch { "Exception occurred" }
}

Get groups in folder permissions, and export the members of the groups to csv

I am trying to Get the groups authority behind each folder of a drive and the username of each Member of the group, then export it to a CSV File.
The problem is that the group has the directory name before the group e.g. gescogroup/GR_blablabla, so I remove Gescogroup\ using (Remove(0,12)).
As you see I first let the user chose the folder of the drive they want to analyze, then the code runs through the folders inside the drive and for each folder it gets the group, then with the name of the group (Removing the "Create owner, "Administrators", "Built "in etc) I should get the members.
My code doesn't work, but I get no errors. Can you guys help me?
cls
$result = [System.Windows.MessageBox]::Show("Select the path of the drive.`n"+"Once the Drive is selected, a excel file will be made with all the informations`n"+"of the selected Harddrive's directory premissions")
if ($result = "OK")
{
Add-Type -AssemblyName System.Windows.Forms
$FolderBrowser = New-Object System.Windows.Forms.FolderBrowserDialog
[void]$FolderBrowser.ShowDialog()
$Selection = $FolderBrowser.SelectedPath
}
$result2 = [System.Windows.MessageBox]::Show("Pleas select where to save your file")
if ($result2 = "OK")
{
Add-Type -AssemblyName System.Windows.Forms
$FolderBrowser2 = New-Object System.Windows.Forms.FolderBrowserDialog
[void]$FolderBrowser2.ShowDialog()
$FolderBrowser2.Description = "Select where to save your file"
$Selection2 = $FolderBrowser2.SelectedPath
}
$title = "ADPermissions.csv"
$title2 = "ADPermissions2.csv"
$ss =$Selection1 -replace '[\W]', ''
$subtitle = "HardDrive"+ $ss
$OutFile = ($Selection2+"\"+$subtitle+$title)
Write-Host = $OutFile
Remove-Item $OutFile
$Header = "Folder Path,IdentityReference,names"
$RootPath = $Selection
$Folders = dir $RootPath | where {$_.psiscontainer -eq $true}
try {
foreach ($Folder in $Folders){$ACLs = get-acl $Folder.fullname | ForEach-Object { $_.Access }
Foreach ($ACL in $ACLs){
if($ACL.IdentityReference -notlike "Administrators" -and $ACL.IdentityReference -notlike "Creator Owner"-and $ACL.IdentityReference -notlike "BUILTIN\Administrators" -and $ACL.IdentityReference -notlike "NT AUTHORITY\SYSTEM" -and $ACL.IdentityReference -notlike "System")
{
$strAcl = $ACL.IdentityReference
$strAcls = $ACL.IdentityReference.ToString()
$strUsers=#()
$strNames=$strAcls.Remove(0,12)
$A = Get-ADGroupMember -identity $strNames -Recursive | Get-ADUser -Property DisplayName | Select Name | Sort-Object Name
foreach($strNames in $A)
{
$strUsers+=$A
}
}
}
}
$OutInfo = $Folder.fullname + "," + $trAcl+$strUsers
Add-Content -Value $OutInfo -Path $OutFile | sort-Object -Unique
}catch [System.IO.IOException] {
}
This is the solution:
try {
foreach ($Folder in $Folders){$ACLs = get-acl $Folder.fullname | ForEach-Object { $_.Access }
Foreach ($ACL in $ACLs){
if($ACL.IdentityReference -notlike "Administrators" -and $ACL.IdentityReference -notlike "Creator Owner"-and $ACL.IdentityReference -notlike "BUILTIN\Administrators" -and $ACL.IdentityReference -notlike "NT AUTHORITY\SYSTEM" -and $ACL.IdentityReference -notlike "System")
{
$strAcls = $ACL.IdentityReference.ToString()
$strUsers=#()
$strNames=$strAcls.Remove(0,12)
$A = Get-ADGroupMember -identity $strNames -Recursive | Get-ADUser -Property DisplayName | Select Name | Sort-Object Name
foreach ($env:USERNAME in $A){
$strUsers +=$env:USERNAME
}
$OutInfo = $Folder.fullname + "," + $ACL.IdentityReference + $strUsers
}
}
}
}catch [System.IO.IOException] {
}
}