I have the following PowerShell script in which I can run to get a good mixed report from Office 365.
$Results = #()
$MailboxUsers = get-mailbox -resultsize unlimited
$Statistics = $MailboxUsers | Get-MailboxStatistics | select *
$Licenses = Get-MsolUser | select *
$Permissions = $MailboxUsers | Get-MailboxPermission | select *
foreach($user in $mailboxusers)
{
$UPN = $user.userprincipalname
$Properties = #{
Name = $user.name
UPN = $UPN
Alias = $user.alias
RecipientTypeDetails = $user.RecipientTypeDetails
Identity = ($Permissions | where {$_.Identity -eq ($user).DisplayName}).Identity
User = ($Permissions | where {$_.Identity -eq ($user).DisplayName}).User
AccessRights = ($Permissions | where {$_.Identity -eq ($user).DisplayName}).AccessRights
IsInherited = ($Permissions | where {$_.Identity -eq ($user).DisplayName}).IsInherited
Deny = ($Permissions | where {$_.Identity -eq ($user).DisplayName}).Deny
IsLicensed = ($Licenses | where {$_.UserPrincipalName -eq ($user).UserPrincipalName}).IsLicensed
TotalItemSize = ($Statistics | where {$_.DisplayName -eq ($user).DisplayName}).TotalItemSize
ItemCount = ($Statistics | where {$_.DisplayName -eq ($user).DisplayName}).ItemCount
License = ($Licenses | where {$_.UserPrincipalName -eq ($user).UserPrincipalName}).Licenses.AccountSkuId
}
$Results += New-Object psobject -Property $properties
}
$results | sort name | fl
However, when I run this, 5 objects Identity, User, AccessRights, IsInherited and Deny all show multiple results mixed into the same output.
Even if I change the last line to this:
$results | sort name | Out-GridView
This also shows the same 5 objects Identity, User, AccessRights, IsInherited and Deny all bunched together.
What I am looking for is to separate the 5 objects Identity, User, AccessRights, IsInherited and Deny onto different lines, and for the rest of the objects, just to repeat e.g. Name, UPN, License, RecipientTypeDetails, TotalItemSize, Alias, IsLicensed and ItemCount would be repeated beside each result in the 5 objects Identity, User, AccessRights, IsInherited and Deny.
This way I can do more things with the output, put it into Excel for example and massage the results.
I would use note properties individually defined like below to build your output results, It works for me and can easily be exported to what ever format you need from here. Check that i got all the properties and in the right order.
foreach($user in $mailboxusers)
{
$UPN = $user.userprincipalname
$match = New-Object -TypeName PSObject
$match | Add-Member -Type NoteProperty -Name "Name" -Value $user.name
$match | Add-Member -Type NoteProperty -Name "UPN" -Value $UPN
$match | Add-Member -Type NoteProperty -Name "Alias" -Value $user.alias
$match | Add-Member -Type NoteProperty -Name "RecipientTypeDetails" -Value $user.RecipientTypeDetails
$match | Add-Member -Type NoteProperty -Name "Identity" -Value ($Permissions | where {$_.Identity -eq ($user).DisplayName}).Identity
$match | Add-Member -Type NoteProperty -Name "User" -Value ($Permissions | where {$_.Identity -eq ($user).DisplayName}).User
$match | Add-Member -Type NoteProperty -Name "AccessRights" -Value ($Permissions | where {$_.Identity -eq ($user).DisplayName}).AccessRights
$match | Add-Member -Type NoteProperty -Name "IsInherited" -Value ($Permissions | where {$_.Identity -eq ($user).DisplayName}).IsInherited
$match | Add-Member -Type NoteProperty -Name "Deny" -Value ($Permissions | where {$_.Identity -eq ($user).DisplayName}).Deny
$match | Add-Member -Type NoteProperty -Name "IsLicensed" -Value ($Licenses | where {$_.UserPrincipalName -eq ($user).UserPrincipalName}).IsLicensed
$match | Add-Member -Type NoteProperty -Name "TotalItemSize" -Value ($Statistics | where {$_.DisplayName -eq ($user).DisplayName}).TotalItemSize
$match | Add-Member -Type NoteProperty -Name "ItemCount" -Value ($Statistics | where {$_.DisplayName -eq ($user).DisplayName}).ItemCount
$match | Add-Member -Type NoteProperty -Name "License" -Value ($Licenses | where {$_.UserPrincipalName -eq ($user).UserPrincipalName}).Licenses.AccountSkuId
$Results += $match
}
Related
How do I add the value of $i as a new parameter to the object so that if $i is part of distinguishedName?
param([string[]]$Country="Norway,Denmark")
foreach ($i in $Country)
{
$users += Get-ADUser -searchbase "ou=$i,ou=FMS,dc=ce,dc=xxxx,dc=net" -ldapfilter $ldapfilter -properties CN,SamAccountName,mail,title,department,company,pager,employeeNumber,distinguishedName,extensionAttribute12
$users | Add-Member -MemberType NoteProperty -Name "OOU" -Force -Value ""
{missing code to add $i as value for property .OOU}
}
$users | Add-Member -MemberType NoteProperty -Name "license" -Force -Value ""
$users | where extensionAttribute12 -Like "*EOP1*" | %{$_.license="EOP1"}
$users | where extensionAttribute12 -Like "*E1*" | %{$_.license="E1"}
$users | where extensionAttribute12 -Like "*E3*" | %{$_.license="E3"}
I have tried to do the same as with the where clause in the bottom part, but the foreach loop makes it overwrite all values with the last member of $i
Use the -Value parameter to specify the initial value of a new property:
$users | Add-Member -MemberType NoteProperty -Name "OOU" -Force -Value $i
To avoid re-assigning the newest values to all the existing users that have already received their new OOP property, use an intermediary variable to hold the output from Get-ADUser:
foreach ($i in $Country)
{
$country_users = Get-ADUser -searchbase "ou=$i,ou=FMS,dc=ce,dc=xxxx,dc=net" -ldapfilter $ldapfilter -properties CN,SamAccountName,mail,title,department,company,pager,employeeNumber,distinguishedName,extensionAttribute12
$users += #($country_users | Add-Member -MemberType NoteProperty -Name "OOU" -Force -Value $i)
}
Works:
$Names = 1..5 | % { new-object psobject | add-member -Type NoteProperty -Name Name -Value "MyName" -PassThru } | group Name -AsHashTable
$Names.MyName
Doesn't work:
$Names = 1..5 | % { new-object psobject | add-member -Type ScriptProperty -Name Name -Value {"MyName"} -PassThru } | group Name -AsHashTable
$Names.MyName
The reason you're unable to access the values in the hash-table by prop name or key-based access is that the keys/props are wrapped in PSObjects. There was a Github issue to fix this in Powershell Core, but it will likely remain forever in Windows Powershell.
If you want to convert to a hash-table after grouping, and want to access some of the grouped values by property name or key-based access do this:
$Names = 1..5 | ForEach-Object {
New-Object PsObject | Add-Member -Type ScriptProperty -Name Name -Value { return "MyName"} -PassThru
} | Group-Object -Property 'Name' -AsHashTable -AsString
$Names.MyName
$Names['MyName']
If you want to convert to a hash-table after grouping, and want to access all the grouped values at once, do this:
$Names = 1..5 | ForEach-Object {
New-Object PsObject | Add-Member -Type ScriptProperty -Name Name -Value { return "MyName"} -PassThru
} | Group-Object -Property 'Name' -AsHashTable
$Names.Values
If you're not converting to a hash-table after the grouping, and want to access the data in $Names.Group, you'll need to expand that property.
$Names = 1..5 | % {
new-object psobject | add-member -Type ScriptProperty -Name Name -Value {"MyName"} -PassThru
} | Group-Object -Property 'Name'
$Names | Select-Object -ExpandProperty Group
I'm Trying to retrieve the exact size of the profile in windows machine.
below is my code and O/P
$profiles = Get-ChildItem C:\Users | ?{Test-path C:\Users\$_\NTUSER.DAT} | Select -ExpandProperty Name
foreach($profile in $profiles)
{
$largeprofile = Get-ChildItem C:\Users\$profile -recurse | Measure-Object -Sum length | Select -ExpandProperty Sum
$largeprofile = [math]::Round(($largeprofile/1MB),2) + "MB"
if($largeprofile -lt 20){Continue}
$object = New-Object -TypeName PSObject
$object | Add-Member -MemberType NoteProperty -Name Name -Value $profile
$object | Add-Member -MemberType NoteProperty -Name "Size(MB)" -Value $largeprofile
($object | fl | Out-String).Trim();Write-Output "`n"
}
O/P
Name : admin
Size(MB) : 34.62
however exact size of the folder is 181MB,powershell is not able to read all the folders and files inside the parent folder, how can I get the exact size which is displayed in a properties of the folder.
Note : For Folders other than the profile folder o/p is correct.
You will have to add the parameter -Force to Get-ChildItem when you are Recursing the directory. From the docs Get-ChildItem the -Force parameter:
Allows the cmdlet to get items that cannot otherwise not be accessed
by the user, such as hidden or system files.
Additionally, you will want to add -ErrorAction SilentlyContinue so you don't get flooded with Access Denied errors. These changes makes your code look like this:
$profiles = Get-ChildItem C:\Users | ?{Test-path C:\Users\$_\NTUSER.DAT} | Select -ExpandProperty Name
foreach($profile in $profiles)
{
$largeprofile = Get-ChildItem C:\Users\$profile -Recurse -Force -ErrorAction SilentlyContinue | Measure-Object -Sum length | Select -ExpandProperty Sum
$largeprofile = [math]::Round(($largeprofile/1MB),2) + "MB"
if($largeprofile -lt 20){Continue}
$object = New-Object -TypeName PSObject
$object | Add-Member -MemberType NoteProperty -Name Name -Value $profile
$object | Add-Member -MemberType NoteProperty -Name "Size(MB)" -Value $largeprofile
($object | fl | Out-String).Trim();Write-Output "`n"
}
For a given mailbox, I want to list of any users who have any of the following permissions:
send as
send on behalf of
full access
I haven't been able to find a simple way to get all 3 at once, so I have been going at it on a per permission basis...
get-exolmailbox -identity "example#example.com" | get-exolmailboxpermission | where { ($_.AccessRights -eq "FullAccess") -and ($_.IsInherited -eq $false) -and -not ($_.User -like "NT AUTHORITY\SELF") }
get-exolmailbox -Identity "example#example.com" | Get-ADPermission | ? { ($_.ExtendedRights -like "*send*") -or ($_.ExtendedRights -like "*full*") -and -not ($_.User -like "*\self*") } | FT -auto User,ExtendedRights
get-exolmailbox -identity "example#example.com" | fl displayname, grantsendonbehalfto
Is there was a more elegant way to get that same info before I put some time into figuring out how to format the results the way I want?
I would prefer to end up with an excel file that lists each user by display name and which permissions they have to the mailbox.
Something like this should do what you want, it creates a custom object and assigns the info from your commands to its properties.
$emailaddress = "user1#example.com","user2#example.com"
$MailboxPermissions = #()
foreach ($email in $emailaddress)
{
$exolmailbox = get-exolmailbox -identity $email
$FullAccess = $exolmailbox | where { ($_.AccessRights -eq "FullAccess") -and ($_.IsInherited -eq $false) -and -not ($_.User -like "NT AUTHORITY\SELF") }
$SendAs = $exolmailbox | Get-ADPermission | ? { ($_.ExtendedRights -like "*send*") -or ($_.ExtendedRights -like "*full*") -and -not ($_.User -like "*\self*") }
$MailboxInfo = New-Object System.Object
$MailboxInfo | Add-Member -type NoteProperty -name DisplayName -value $exolmailbox.displayname
$MailboxInfo | Add-Member -type NoteProperty -name FullAccess -value $FullAccess
$MailboxInfo | Add-Member -type NoteProperty -name SendAsUser -value $SendAs.User
$MailboxInfo | Add-Member -type NoteProperty -name SendAsExtendedRights -value $SendAs.ExtendedRights
$MailboxInfo | Add-Member -type NoteProperty -name GrantSendOnBehalfTo -value $exolmailbox.grantsendonbehalfto
$MailboxPermissions += $MailboxInfo
}
$MailboxPermissions
Note: I can't test this as I can't find anything online that references get-exolmailbox, and I've only ever seen/used get-mailbox before.
below code when inputting a few users, but fails is not returning expected results when querying for all users in AD. Not understanding why it's failing on bulk users versus a relatively small user list
Code below:
$Users = #('user1',"user2",'user3','user4')
$Mailboxes = $Users | Get-ADuser -pr *
$OU = 'DC=local,DC=local,DC=org'
$Mailboxes = Get-ADUser -Filter {SamAccountName -notlike '*$*'} -pr samaccountname
$Mailboxes = Get-ADUser -Filter * -SearchBase $OU -Properties samaccountname
foreach ($Mbx in $Mailboxes)
{
$ADUser = Get-ADUser $Mbx.SamAccountName -Properties * #Enabled,AccountExpirationDate
$UserObj = New-Object PSObject
$UserObj | Add-Member NoteProperty -Name "Username" -Value $ADUser.SamAccountName
If($mbx.msExchRecipientTypeDetails -eq $null)
{
$UserObj | Add-Member NoteProperty -Name "E-Mail" -Value "NoEmailAddress"
$UserObj | Add-Member NoteProperty -Name "email ItemCount" -Value "NoMailBox"
$UserObj | Add-Member NoteProperty -Name "TotalItemSize(GB)" -Value "NoMailBox"
Write-Host $Mbx.SamAccountName "has no mailbox" -ForegroundColor green
}
Else
{
If($mbx.msExchRecipientTypeDetails -eq 1)
{
$stats = $Mbx.EmailAddress | Get-MailboxStatistics | Select-Object TotalItemSize,TotalDeletedItemSize,ItemCount,LastLogonTime,LastLoggedOnUserAccount
$MbxSizeb = $stats.TotalItemSize -replace "(.*\()|,| [a-z]*\)"
$Tmp_gb = $MbxSizeb/1GB
$MbxSizeGB = [math]::Round($Tmp_gb,2)
$UserObj | Add-Member NoteProperty -Name "E-Mail" -Value $ADUser.EmailAddress
$UserObj | Add-Member NoteProperty -Name "email ItemCount" -Value $stats.ItemCount
$UserObj | Add-Member NoteProperty -Name "TotalItemSize(GB)" -Value $MbxSizeGB
}
}
$Report = $Report += $UserObj
}
Results with selected users
enter image description here
Results against all users:
enter image description here
You are missing the property msExchRecipientTypeDetails when populating the $Mailboxes variable. Lines 5 and 6 should read -Properties msExchRecipientTypeDetails
Update: So this wasn't completely correct. You can use your code if you change If($mbx.msExchRecipientTypeDetails -eq $null) to If($aduser.msExchRecipientTypeDetails -eq $null). However, you really don't need to get the ADUser again. $Mailboxes is a collection of ADUsers. Changes lines 2,6,7 to -Properties EmailAddress,msExchRecipientTypeDetails,SamAccountName
$Users = #('user1',"user2",'user3','user4')
$Mailboxes = $Users | Get-ADuser -Properties EmailAddress,msExchRecipientTypeDetails,SamAccountName
#$OU = 'DC=local,DC=local,DC=org'
#$Mailboxes = Get-ADUser -Filter {SamAccountName -notlike '*$*'} -Properties EmailAddress,msExchRecipientTypeDetails,SamAccountName
#$Mailboxes = Get-ADUser -Filter * -SearchBase $OU -Properties EmailAddress,msExchRecipientTypeDetails,SamAccountName
$Report = #()
foreach ( $Mbx in $Mailboxes ) {
switch ( $Mbx.msExchRecipientTypeDetails ) {
1 {
$Stats = $Mbx.EmailAddress | Get-MailboxStatistics | Select-Object TotalItemSize,ItemCount
$Report += [pscustomobject] #{
'Username' = $_.SamAccountName
'E-Mail' = $Mbx.EmailAddress
'E-Mail ItemCount' = $Stats.ItemCount
'TotalItemSize(GB)' = ( [math]::Round( ( $Stats.TotalItemSize -replace "(.*\()|,| [a-z]*\)" )/1GB ),2 )
}
break
}
default {
$Report += [pscustomobject] #{
'Username' = $_.SamAccountName
'E-Mail' = 'NoEmailAddress'
'E-Mail ItemCount' = 'NoMailBox'
'TotalItemSize(GB)' = 'NoMailBox'
}
break
}
}
}
#Shawn Esterman - thanks for the input -- below code works like a charm. Explicitly stated properties to search on.
cls
$Users = #()
$Report = #()
$UserObj = #()
$ADUser = #()
$Mbx = #()
$OU = #()
$Mailboxes = #()
$Users = #("user1",'user2','user3','user4','user5')
$Mailboxes = $Users | Get-ADuser -Properties EmailAddress,msExchRecipientTypeDetails,SamAccountName
$OU = 'DC=local,DC=local,DC=local'
$Mailboxes = Get-ADUser -SearchBase $OU -Filter {SamAccountName -notlike '*$*'} -ResultSetSize 50 -Properties EmailAddress,msExchRecipientTypeDetails,SamAccountName
foreach ($Mbx in $Mailboxes)
{
$UserObj = New-Object PSObject
$UserObj | Add-Member NoteProperty -Name "Username" -Value $Mbx.SamAccountName
If($mbx.msExchRecipientTypeDetails -eq $null)
{
$UserObj | Add-Member NoteProperty -Name "E-Mail" -Value "NoEmailAddress"
$UserObj | Add-Member NoteProperty -Name "email ItemCount" -Value "NoMailBox"
$UserObj | Add-Member NoteProperty -Name "TotalItemSize(GB)" -Value "NoMailBox"
Write-Host $Mbx.SamAccountName "has no mailbox" -ForegroundColor green
}
Else
{
If($mbx.msExchRecipientTypeDetails -eq 1)
{
$stats = $Mbx.EmailAddress | Get-MailboxStatistics | Select-Object TotalItemSize,TotalDeletedItemSize,ItemCount,LastLogonTime,LastLoggedOnUserAccount
$MbxSizeb = $stats.TotalItemSize -replace "(.*\()|,| [a-z]*\)"
$Tmp_gb = $MbxSizeb/1GB
$MbxSizeGB = [math]::Round($Tmp_gb,2)
$UserObj | Add-Member NoteProperty -Name "E-Mail" -Value $Mbx.EmailAddress
$UserObj | Add-Member NoteProperty -Name "email ItemCount" -Value $stats.ItemCount
$UserObj | Add-Member NoteProperty -Name "TotalItemSize(GB)" -Value $MbxSizeGB
}
}
$Report = $Report += $UserObj
}