I have been tasked with pulling a list of all MFA enabled/disabled accounts in our environment. I found a script and modified with with extra fields I needed, one of them being Last Log On Time. I need this basically for to filter through the report to remove any type of service accounts/ external account ect. The code I have just outputs a blank field when exporting to the csv.
I've tried every variation of LastLogon I could find (time,date,ect)
$Report = #()
$i = 0
$Accounts = (Get-MsolUser -All | ? {$_.StrongAuthenticationMethods -ne $Null} | Sort DisplayName)
ForEach ($Account in $Accounts) {
Write-Host "Processing" $Account.DisplayName
$i++
$Methods = $Account | Select -ExpandProperty StrongAuthenticationMethods
$MFA = $Account | Select -ExpandProperty StrongAuthenticationUserDetails
$State = $Account | Select -ExpandProperty StrongAuthenticationRequirements
$Methods | ForEach { If ($_.IsDefault -eq $True) {$Method = $_.MethodType}}
If ($State.State -ne $Null) {$MFAStatus = $State.State}
Else {$MFAStatus = "Disabled"}
$ReportLine = [PSCustomObject][Ordered]#{
User = $Account.DisplayName
UPN = $Account.UserPrincipalName
Department = $Account.Department
Office = $Account.Office
LastLogon = $Account.LastLogon
MFAMethod = $Method
MFAPhone = $MFA.PhoneNumber
MFAEmail = $MFA.Email
MFAStatus = $MFAStatus }
$Report += $ReportLine }
Write-Host $i "accounts are MFA-enabled"
$Report | Export-CSV -NoTypeInformation c:\temp\MFAUsers.CSV
Any help with exporting the last log on date would be great.
I cannot test this, but I think you need LastLogon = (Get-MailboxStatistics -Identity $Account.UserPrincipalName).LastLogonTime.
As a sidenote, adding objects to an array is slow and there is an easier method of collecting the emitted objects into the $Report variable:
$mfaEnabled = 0
$Accounts = (Get-MsolUser -All | ? {$_.StrongAuthenticationMethods -ne $Null} | Sort DisplayName)
$Report = foreach ($Account in $Accounts) {
Write-Host "Processing" $Account.DisplayName
$Methods = $Account | Select -ExpandProperty StrongAuthenticationMethods
$MFA = $Account | Select -ExpandProperty StrongAuthenticationUserDetails
$State = $Account | Select -ExpandProperty StrongAuthenticationRequirements
$Methods | ForEach-Object { If ($_.IsDefault -eq $True) {$Method = $_.MethodType}}
If ($State.State) {$MFAStatus = $State.State} else {$MFAStatus = "Disabled"}
# update the counter for MFA Enabled users
if ($MFAStatus -eq 'Enabled') { $mfaEnabled++ }
# just emit the PSObject here, it will be collected in the $Report variable.
# also, no need to use [ordered] on [PSCustomObject]
[PSCustomObject]#{
User = $Account.DisplayName
UPN = $Account.UserPrincipalName
Department = $Account.Department
Office = $Account.Office
LastLogon = (Get-MailboxStatistics -Identity $Account.UserPrincipalName).LastLogonTime
MFAMethod = $Method
MFAPhone = $MFA.PhoneNumber
MFAEmail = $MFA.Email
MFAStatus = $MFAStatus
}
}
Write-Host "$mfaEnabled accounts are MFA-enabled"
$Report | Export-CSV -NoTypeInformation c:\temp\MFAUsers.CSV
Related
im sorry if my english is bad. but here is what im trying to do.
atm i have a script that shows Mailbox size. and a script that shows archive size. im using these scripts to add information to Hudu later.
is there a way to get this information into one table?
below is how i'm getting archive info:
#Getting archive info
$Result = #()
$mailboxes = Get-Mailbox -ResultSize Unlimited
$totalmbx = $mailboxes.Count
$i = 1
$mailboxes | ForEach-Object {
$i++
$mbx = $_
$size = $null
Write-Progress -activity "Processing $mbx" -status "$i out of $totalmbx completed"
if ($mbx.ArchiveStatus -eq "Active") {
$mbs = Get-MailboxStatistics $mbx.UserPrincipalName
if ($mbs.TotalItemSize -ne $null) {
$size = [math]::Round(($mbs.TotalItemSize.ToString().Split('(')[1].Split(' ')[0].Replace(',', '') / 1MB), 2)
}
else {
$size = 0
}
}
$Result += New-Object -TypeName PSObject -Property $([ordered]#{
UserName = $mbx.DisplayName
UserPrincipalName = $mbx.UserPrincipalName
ArchiveStatus = $mbx.ArchiveStatus
ArchiveName = $mbx.ArchiveName
ArchiveState = $mbx.ArchiveState
ArchiveMailboxSizeInMB = $size
ArchiveWarningQuota = if ($mbx.ArchiveStatus -eq "Active") { $mbx.ArchiveWarningQuota } Else { $null }
ArchiveQuota = if ($mbx.ArchiveStatus -eq "Active") { $mbx.ArchiveQuota } Else { $null }
AutoExpandingArchiveEnabled = $mbx.AutoExpandingArchiveEnabled
})
}
$Result | Select UserName, UserPrincipalName, ArchiveMailboxSizeInMB, ArchiveWarningQuota, ArchiveQuota, AutoExpandingArchiveEnabled, ArchiveState| Format-Table
the output from that script would look something like this:
UserName UserPrincipalNam ArchiveMailboxSizeInMB ArchiveWarningQuota ArchiveQuota AutoExpandingArchiveEnabled ArchiveState
-------- ----------------- ---------------------- ------------------- ------------ --------------------------- ------------
User user#domain.com 14,12 90 GB (96,636,764,160 bytes) 100 GB (107,374,182,400 bytes) False Local
User user#domain.com False None
User user#domain.com False None
User user#domain.com 2,42 90 GB (96,636,764,160 bytes) 100 GB (107,374,182,400 bytes) False Local
i would like that table to also show: Mailbox Size, Item count and last logon time. like you get by running:
$mailboxstatspruser = $mailboxes | Get-MailboxStatistics | select-object DisplayName, #{name=”TotalItemSize (GB)”;expression={[math]::Round((($_.TotalItemSize.Value.ToString()).Split(“(“)[1].Split(” “)[0].Replace(“,”,””)/1GB),2)}},ItemCount,LastLogonTime
is there a way to match these to together and get a table with information from both? adding fields into $result is ofc easy. but then the output looks messed up. so matching the tables is where im stuck atm.
Translating calculated property tables to a single hashtable of properties is pretty straight forward:
Use the Name value as the key
Use the contents of the Expression value as the value
Replace $_ with the name of the source variable (in this case $mbs)
$Result += New-Object -TypeName PSObject -Property $([ordered]#{
UserName = $mbx.DisplayName
UserPrincipalName = $mbx.UserPrincipalName
ArchiveStatus = $mbx.ArchiveStatus
ArchiveName = $mbx.ArchiveName
ArchiveState = $mbx.ArchiveState
ArchiveMailboxSizeInMB = $size
ArchiveWarningQuota = if ($mbx.ArchiveStatus -eq "Active") { $mbx.ArchiveWarningQuota } Else { $null }
ArchiveQuota = if ($mbx.ArchiveStatus -eq "Active") { $mbx.ArchiveQuota } Else { $null }
AutoExpandingArchiveEnabled = $mbx.AutoExpandingArchiveEnabled
'TotalItemSize (GB)' = [math]::Round((($mbs.TotalItemSize.Value.ToString()).Split("(")[1].Split(" ")[0].Replace(",","")/1GB),2)
ItemCount = $mbs.ItemCount
LastLogonTime = $mbs.LastLogonTime
})
I updated it a little bit:
Fixed issue where you always skip the first 2 mailboxes (start with i = 0 and i++ at the end of the loop)
Added recoverable items folder so you can also report on hold sizes (very slow, but useful)
Added mailbox sizes
removed some stuff I didn't need
Updated to EXO cmdlets for more speed
$Domain = "*#domain.com" #change to domain you need
$mailboxes = Get-Mailbox -ResultSize Unlimited -filter "(emailaddresses -like '$Domain') -and (recipienttypedetails -ne 'RoomMailbox')"
$totalmbx = $mailboxes.Count
$Result=#()
$i = 0
$mailboxes | ForEach-Object {
$mbx = $_
$size = $null
$RecoverableItems = $null
$RecoverableItemsSize = $null
Write-Progress -activity "Processing $mbx" -status "$i out of $totalmbx completed"
$mbs = Get-EXOMailboxStatistics $mbx.UserPrincipalName
$Size = [math]::Round(($mbs.TotalItemSize.ToString().Split('(')[1].Split(' ')[0].Replace(',','')/1MB),2)
$RecoverableItems = Get-EXOMailboxFolderStatistics $mbx.UserPrincipalName -FolderScope RecoverableItems | Where-Object {$_.name -eq "Recoverable Items"}
$RecoverableItemsSize = [math]::Round(($RecoverableItems.FolderAndSubfolderSize.ToString().Split('(')[1].Split(' ')[0].Replace(',','')/1MB),2)
if ($mbx.ArchiveStatus -eq "Active"){
$mbsArchive = Get-EXOMailboxStatistics $mbx.UserPrincipalName -archive
if ($mbs.TotalItemSize -ne $null){
$ArchiveSize = [math]::Round(($mbsArchive.TotalItemSize.ToString().Split('(')[1].Split(' ')[0].Replace(',','')/1MB),2)
$ArchiveRecoverableItems = Get-EXOMailboxFolderStatistics $mbx.UserPrincipalName -Archive -FolderScope RecoverableItems | Where-Object {$_.name -eq "Recoverable Items"}
$ArchiveRecoverableItemsSize = [math]::Round(($ArchiveRecoverableItems.FolderAndSubfolderSize.ToString().Split('(')[1].Split(' ')[0].Replace(',','')/1MB),2)
}else{
$ArchiveSize = 0
$ArchiveRecoverableItems = 0
$ArchiveRecoverableItemsSize = 0
}
}
$Result += New-Object -TypeName PSObject -Property $([ordered]#{
UserName = $mbx.DisplayName
UserPrincipalName = $mbx.UserPrincipalName
ArchiveName =$mbx.ArchiveName
MailboxSizeInMB = $Size
ArchiveMailboxSizeInMB = $ArchiveSize
HoldSize = $RecoverableItemsSize
ArchiveHoldSize = $ArchiveRecoverableItemsSize
})
$i++
}
$Result | Export-CSV "C:\Temp\Archive-Mailbox-Report.csv" -NoTypeInformation -Encoding UTF8
I am trying to get a number of how many people with specific titles are in specific groups.
What my approach is:
I am looking for users with specific titles.
I am looping over those users and looking for their groups they are in
Then I am looping over each group and trying to add .csv entry when there is a new one for that specific title, if group is listed, I am trying to just increment the counter.
I think that my approach is slow - every time I export and import .csv file, but I am sure there is a way to work on a imported file.
Also I have strange error: when importing test.csv I have like 10 entries instead of one. How to fix that?
My code:
clear
$Roles = Get-Content 'C:\Users\DWodzinski-admin\Documents\Titles.txt'
$Users = #()
Foreach ($Item in $Roles){
$Users += Get-ADUser -Filter {title -like $Item} -properties title, SamAccountName | Select SamAccountName, title
}
Foreach ($User in $Users){
$AdGroups = Get-ADPrincipalGroupMembership $User.SamAccountName | Select Name
foreach ($thing in $AdGroups) {
$name = $thing.name
$csv = Import-Csv "C:\Users\DWodzinski-admin\Documents\test.csv"
foreach($i in $csv){
if($i.Group -eq $name -and $i.Title -eq $User.title) {
$i.Count += 1
Export-CSV "C:\Users\DWodzinski-admin\Documents\test.csv" -NoTypeInformation
} else {
$NewCsvEntry = #{
Title = $User.title
Group = $name
Count = 0
}
[PSCustomObject]$NewCsvEntry | Export-CSV "C:\Users\DWodzinski-admin\Documents\test.csv" -NoTypeInformation -Append
}
$i
}
}
$csv | Export-CSV "C:\Users\DWodzinski-admin\Documents\test.csv" -NoTypeInformation -Append
}
i changed it so that it only imports your csv once, at the start, and exports (overwrites) it at the end. maybe it also fixes your issue with the 10 entries, try it out.
clear
$csv = Import-Csv "C:\Users\DWodzinski-admin\Documents\test.csv"
$Roles = Get-Content 'C:\Users\DWodzinski-admin\Documents\Titles.txt'
$Users = #()
Foreach ($Item in $Roles) {
$Users += Get-ADUser -Filter { title -like $Item } -properties title, SamAccountName | Select SamAccountName, title
}
Foreach ($User in $Users) {
$AdGroups = Get-ADPrincipalGroupMembership $User.SamAccountName | Select Name
foreach ($thing in $AdGroups) {
$name = $thing.name
foreach ($i in $csv) {
if ($i.Group -eq $name -and $i.Title -eq $User.title) {
$i.Count += 1
}
else {
$newCsvEntry = [PSCustomObject]#{
Title = $User.title
Group = $name
Count = 0
}
$csv += $newCsvEntry
}
$i
}
}
}
$csv | Export-CSV "C:\Users\DWodzinski-admin\Documents\test.csv" -NoTypeInformation -Force
If anyone want to know how I did it, I created ArrayList with CustomObjects:
clear
$Roles = Get-Content 'C:\Users\DWodzinski-admin\Documents\Titles.txt'
$Users = #()
$List = New-Object System.Collections.ArrayList
$Object = [PSCustomObject]#{
Name = 'Pierwszy';
Title = 'Czarny';
Count = 0;
}
$List.add($Object)
Foreach ($Item in $Roles){
$Users += Get-ADUser -Filter {title -like $Item} -properties title, SamAccountName | Select SamAccountName, title
}
Foreach ($User in $Users){
$AdGroups = Get-ADPrincipalGroupMembership $User.SamAccountName | Select Name
foreach($Group in $AdGroups){
if($List | Where Name -eq $Group.name | Where Title -eq $User.title){
$temp = $List | Where Name -eq $Group.name | Where Title -eq $User.title
$temp.Count += 1
} else {
$Object = [PSCustomObject]#{
Name = $Group.Name;
Title = $User.title;
Count = 1;
}
$List.add($Object)
}
}
}
$FilePathLocation = "C:\Users\DWodzinski-admin\Documents\test.csv"
$List | Export-Csv -Path $FilePathLocation -NoTypeInformation
I am trying to create a csv file which contains the username and the group memberships from a list of usernames to a CSV file.
But the CSV file is formatted as below
******;"CN=Cal_ACABLHolidayCalendar_Editor
Username and group in 1 cell
$list = Get-Content c:\Tools\Powershell\ACA\userlist.txt
$list | `
%{
$user = $_;
get-aduser $user -Properties memberof | `
select -expand memberof | `
%{new-object PSObject -property #{User=$user;Group=$_;}} `
} |
export-csv –Path "C:\Tools\Powershell\ADUsers.csv" -Delimiter ‘;’ –NoTypeInformation -Encoding UTF8
How can I have the formatting as the first cell with the username and the below cells with the groups
Export-CSV is the wrong way to achieve your desired solution.
You should be better with something like this:
$excelfile = "C:\Daten\test.xlsx"
###Excel Parameter###
$excel = New-Object -COM "Excel.Application"
$excel.displayalerts = $false
$excel.visible = $false
$excel.usercontrol = $false
$Workbook=$excel.Workbooks.open($excelfile)
$Worksheet=$Workbook.Worksheets.Item(1)
$Worksheet.Activate() | Out-null
$x = 1
$y = 1
$list = get-content c:\daten\list.txt
foreach ($user in $list){
$groups = (get-aduser $user -Properties memberof | select -expand memberof | %{new-object PSObject -property #{User=$user;Group=$_;}} | select -ExpandProperty Group)
$z = $groups.count
$excel.cells.item($y,$x) = $user
for ($i = 2; $i -le $groups.count+1; $i++)
{
$excel.cells.item($i,$x) = $groups[$i]
}
$x=$x+1
}
$Workbook.Save()
$Workbook.Close()
get-process *excel* | kill -Force
Its not 100% correct. Something is wrong with the counter of the username. First user works good though.
I need to modify the below PowerShell script to show two more column called RecipientDetailsType and FullAccess.
The below PowerShell code is already working, but I need to get two more additional columns.
$DataPath = "C:\TEMP\Delegates-Results.csv"
$Results = #()
$MailboxUsers = Get-Mailbox -ResultSize Unlimited -Database CAB-DB02
foreach($user in $mailboxusers) {
$UPN = $user.UserPrincipalName
$MbxStats = Get-MailboxStatistics $UPN
$UserNotes = Get-User $UPN
$delegates = #(Get-MailboxPermission -Identity $UPN |
Where-Object { ($_.AccessRights -like "*FullAccess*") -and
(-not $_.IsInherited) -and
($_.User.toString() -ne "NT AUTHORITY\SELF") -and
($_.User.toString() -notlike '*Discovery Management*') } |
Select-Object #{Name='Delegate'; Expression={(Get-Recipient $_.User.toString()).DisplayName}},
#{Name='AccessRights';Expression={$_.AccessRights -join ', '}})
$Properties = #{
Name = $user.name
PrimarySmtpAddress = $user.PrimarySmtpAddress
RecipientTypeDetails = $user.RecipientTypeDetails
FullAccess = $user.FullAccess
UPN = $UPN
Alias = $user.alias
OU = $user.organizationalunit
Server = $MbxStats.servername
Database = $MbxStats.databasename
TotaItemSize = [math]::Round(($MbxStats.TotalItemSize.ToString().Split("(")[1].Split(" ")[0].Replace(",","")/1MB),2)
Delegates = $delegates.Delegate -join ', '
Notes = $UserNotes.Notes
}
$Results += New-Object psobject -Property $properties
}
$Results | Sort-Object -Property TotaItemSize | Select-Object Name,UPN,Alias,RecipientTypeDetails,FullAccess,OU,Server,Database,TotaItemSize,Notes,Delegates | Export-Csv -notypeinformation -Path $DataPath
Have you tried modifying $Properties to:
$Properties = #{
Name = $user.name
PrimarySmtpAddress = $user.PrimarySmtpAddress
RecipientDetailsType = $user.RecepientDetailsType
FullAccess = $user.FullAccess
UPN = $UPN
Alias = $user.alias
OU = $user.organizationalunit
Server = $MbxStats.servername
Database = $MbxStats.databasename
TotaItemSize = [math]::Round(($MbxStats.TotalItemSize.ToString().Split("(")[1].Split(" ")[0].Replace(",","")/1MB),2)
Notes = $UserNotes.Notes
}
$Results | Sort-Object -Property TotaItemSize | Select-Object Name,UPN,Alias,RecepientDetailsType,FullAccess,OU,Server,Database,TotaItemSize,Notes | Export-Csv -notypeinformation -Path $DataPath
If that doesn't work, let me know and I'll try it in our Exchange environment.
I have a script that gives me all members of a group with certain desired information. I want this same format but for all groups that a specified username belongs to. I want information about each group, such as group type (ie security, distribution list). How would I do this? I want a different row for each group, with information about each group in the columns.
Add-PSSnapin Quest.ActiveRoles.ADManagement
$myCol = #()
ForEach ($Group in (Get-QADGroup "CN=research,OU=Security,OU=Groups,DC=xxx,DC=com" -GroupType Security))
{
ForEach ($Member in (Get-QADGroupMember $Group -SizeLimit 0))
{
$myObj = "" | Select Group, Type, Member, Email, Username, Department
$myObj.Group = $Group.Name
$myObj.Type = $Group.groupType
$myObj.Member = $Member.Name
$myObj.Email = $Member.Email
$myObj.Department = $Member.Department
$myObj.Username = $Member.sAMAccountName
$myCol += $myObj
}
}
$myCol | Export-Csv -Path "C:\Users\sdevito\Desktop\test.csv" -NoTypeInformation
or. there is this code that i found that does something similar, but each group is in the same row, different column. i cannot figure out how to edit this code to make each group on a new row.
$alist = "Name`tAccountName`tDescription`tEmailAddress`tLastLogonDate`tManager`tTitle`tDepartment`tCompany`twhenCreated`tAcctEnabled`tGroups`n"
$userlist = Get-ADUser sdevito -Properties * | Select-Object -Property Name,SamAccountName,Description,EmailAddress,LastLogonDate,Manager,Title,Department,Company,whenCreated,Enabled,MemberOf | Sort-Object -Property Name
$userlist | ForEach-Object {
$grps = $_.MemberOf | Get-ADGroup | ForEach-Object {$_.Name} | Sort-Object
$arec = $_.Name,$_.SamAccountName,$_.Description,$_.EmailAddress,$_LastLogonDate,$_.Manager,$_.Title,$_.Department,$_.Company,$_.whenCreated,$_.Enabled
$aline = ($arec -join "`t") + "`t" + ($grps -join "`t") + "`n"
$alist += $aline
}
$alist | Out-File C:\Users\sdevito\Desktop\testt.csv
How about something like:
#Requires -Version 3.0
Add-PSSnapin Quest.ActiveRoles.ADManagement
function Get-UsersGroups {
[cmdletbinding()]
param (
[Parameter(Position=0,Mandatory)][string]$Identity,
[Parameter(Position=1)][ValidateSet('all','nested','normal')][string]$MemberType
)
$user = Get-QADUser -Identity $Identity
switch ( $MemberType ) {
'all' { $groups = $user.AllMemberOf }
'nested' { $groups = $user.NestedMemberOf }
default { $groups = $user.MemberOf }
}
foreach ( $group in $groups ) {
$groupinfo = Get-QADGroup -Identity $group
$props = [ordered]#{
Group = $groupinfo.Name
Type = $groupinfo.GroupType
Member = $user.Name
Email = $user.Email
Department = $user.Department
Username = $user.sAMAccountName
}
$obj = New-Object -TypeName PSObject -Property $props
$obj
}
}
Get-UsersGroups -Identity bob | Export-Csv -Path "C:\Users\sdevito\Desktop\test.csv" -NoTypeInformation