I'm having issues trying to have my script read and apply the AD groups with my script. Right now, it's just posting what's in my script, but I would like to have the script read what's in my .txt file and use it with the rest of my script.
$filePath = "C:\Users\UserName\Downloads\ADGroupList.txt"
Get-Content -Path $filePath
Get-ADGroup -filter {Name -like "$filePath" } -Properties managedBy |
ForEach-Object {
$managedBy = $_.managedBy;
if ($managedBy -ne $null)
{
$manager = (get-aduser -Identity $managedBy -Properties emailAddress);
$managerName = $manager.Name;
$managerEmail = $manager.emailAddress;
}
else
{
$managerName = 'N/A';
$managerEmail = 'N/A';
}
Write-Output $_; } |
Select-Object #{n='Group Name';e={$_.Name}}, #{n='Managed By Name';e={$managerName}}, #{n='Managed By Email';e={$managerEmail}}
Export-Csv -Path "C:\Users\UserName\Documents\ADGroupManagerList.csv"
The easiest way is to loop over the group names you have in the ADGroupList.txt file (assuming this is a list of group names, each on a separate line)
$filePath = "C:\Users\UserName\Downloads\ADGroupList.txt"
# just loop over the group names you have in the text file and capture the output
$result = Get-Content -Path $filePath | ForEach-Object {
$group = Get-ADGroup -Filter "Name -like '$_'" -Properties managedBy
# create an object pre filled in when no manager was found
$obj = [PsCustomObject]#{
'Group Name' = $group.Name
'Managed By Name' = 'N/A'
'Managed By Email' = 'N/A'
}
# test if the ManagedBy is populated
if (-not [string]::IsNullOrWhiteSpace($group.ManagedBy)) {
# try to use the DN in property ManagedBy to find the manager
try {
$manager = Get-ADUser -Identity $group.ManagedBy -Properties EmailAddress -ErrorAction Stop
$obj.'Managed By Name' = $manager.Name
$obj.'Managed By Email' = $manager.EmailAddress
}
catch {
Write-Warning "No user found for '$($group.ManagedBy)'.. Please check AD."
}
}
# output the object so it gets collected in variable $result
$obj
}
# write the file
$result | Export-Csv -Path "C:\Users\UserName\Documents\ADGroupManagerList.csv" -NoTypeInformation
For workaround you can use this powershell script to get the mangedBy of groups.
Get-ADGroup -filter * -Properties managedBy |
ForEach-Object {
$managedBy = $_.managedBy;
if ($managedBy -ne $null)
{
$manager = (get-aduser -Identity $managedBy -Properties emailAddress);
$managerName = $manager.Name;
$managerEmail = $manager.emailAddress;
}
else
{
$managerName = 'N/A';
$managerEmail = 'N/A';
}
Write-Output $_; } |
Select-Object #{n='Group Name';e={$_.Name}}, #{n='Managed By Name';e={$managerName}}, #{n='Managed By Email';e={$managerEmail}}
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
}
I have been fetching both direct members and groups inside local administrators group in our remote machines. I want to get an output like below.
Also , if there are GROUP members inside local admin group then I want to organize only GROUP members like below.
MACHINE01,User01,TRUE,GROUP01;GROUP02
output:
"Computername","Members"
"MACHINE01","contoso\User01 contoso\User02 contoso\GROUP01 contoso\GROUP02
desired output:
Computername,Direct Members,Account Status,Group Members
MACHINE01,User01,TRUE,GROUP01;GROUP02
MACHINE01,User02,FALSE
MACHINE02,User05,TRUE,GROUP04;GROUP05;GROUP12
MACHINE02,User08,FALSE
MACHINE02,User12,FALSE
MACHINE44,User07,TRUE
script :
$server_list = #()
Import-Csv C:\temp\server3.csv | ForEach-Object {$server_list += $_.name}
invoke-command {
$members = net localgroup administrators |
where {$_ -AND $_ -notmatch "command completed successfully"} |
select -skip 4
New-Object PSObject -Property #{
Computername = $env:COMPUTERNAME
Members=$members
}
} -computer $server_list -HideComputerName | Select * -ExcludeProperty RunspaceID, PSComputerName, PSShowComputerName | Export-CSV c:\temp\local_admins2.csv -NoTypeInformation
Get-ADComputer -Filter * -SearchBase "OU=Servers,DC=test,DC=local" | select
name | Export-Csv C:\data\servers3.csv
Output:
"ComputerName","Direct Members","Account Status","Group Members"
"machine01","user01","OK",""
"machine01","user02","Degraded",""
"machine02","user03","OK",""
"machine02","user04","Degraded",""
LASTLY UPDATE OUTPUT WMI:
ComputerName Direct Members Account Status Group Members
------------ -------------- -------------- -------------
**MACHINE01 Administrator Degraded Domain Admins;IT-Admins**
MACHINE01 Theo OK
MACHINE01 LocalAdmin OK
**MACHINE02 Administrator Degraded DBA Admins;Software-Admins**
MACHINE02 Theo OK
MACHINE02 LocalAdmin OK
net localgroup does not output anything that differentiates between users or groups, so if possible, use
Get-LocalGroupMember and Get-LocalUser:
$server_list = (Import-Csv -Path 'C:\temp\server3.csv').name
$result = Invoke-Command -ComputerName $server_list -ScriptBlock {
$members = Get-LocalGroupMember -Group "Administrators"
$groups = $members | Where-Object {$_.ObjectClass -eq 'Group'} | ForEach-Object {($_.Name -split '\\')[-1]}
$users = #($members | Where-Object {$_.ObjectClass -eq 'User'})
if ($users.Count) {
# now loop over the user objects
$users | ForEach-Object {
$name = ($_.Name -split '\\')[-1]
$user = if ($_.PrincipalSource -eq 'Local') {
Get-LocalUser -Name $name -ErrorAction SilentlyContinue
}
else {
Get-ADUser -Filter "SamAccountName -eq '$name'" -ErrorAction SilentlyContinue
}
# output an object
[PsCustomObject]#{
'ComputerName' = $env:COMPUTERNAME
'Direct Members' = $name
'Account Status' = $user.Enabled
'Group Members' = $groups -join ';'
}
# clear the $goups here because you only want to list them once per server
$groups = $null
}
}
else {
# no users, just groups
[PsCustomObject]#{
'ComputerName' = $env:COMPUTERNAME
'Direct Members' = $null
'Account Status' = $null
'Group Members' = $groups -join ';'
}
}
} | Select-Object * -ExcludeProperty PSComputerName, RunspaceId
$result | Export-Csv -Path 'c:\temp\local_admins2.csv' -NoTypeInformation
If module Microsoft.Powershell.LocalAccounts is not available to you, you can experiment with module localaccount, but I have no experience with that..
I don't have that old OSes, so you'll have to test this.
Below uses WMI to query the servers for the group memberships:
$server_list = (Import-Csv -Path 'C:\temp\server3.csv').name
$result = foreach ($server in $server_list) {
$query = "Associators of {Win32_Group.Domain='$server',Name='Administrators'} where Role=GroupComponent"
$members = Get-WmiObject -Query $query -ComputerName $server |
Where-Object { $_.__CLASS -match '(User|Group)' } |
Select-Object Name, Caption,
#{Name = 'ObjectClass'; Expression = {$matches[1]}},
#{Name = 'ComputerName'; Expression = {$_.__SERVER}},
Status, LocalAccount, SID, Domain
$groups = #($members | Where-Object {$_.ObjectClass -eq 'Group'})
$users = #($members | Where-Object {$_.ObjectClass -eq 'User'})
if ($users.Count) {
# now loop over the user objects
$users | ForEach-Object {
# output an object
[PsCustomObject]#{
'ComputerName' = $_.ComputerName
'Direct Members' = $_.Name
'Account Status' = $_.Status
'Group Members' = ($groups.Name | Sort-Object -Unique) -join ';'
}
# clear the $groups here because you only want to list them once per server
$groups = $null
}
}
elseif ($groups.Count) {
# no users, just groups
[PsCustomObject]#{
'ComputerName' = $groups[0].ComputerName
'Direct Members' = $null
'Account Status' = $null
'Group Members' = ($groups.Name | Sort-Object -Unique) -join ';'
}
}
}
$result | Export-Csv -Path 'c:\temp\local_admins2.csv' -NoTypeInformation
Another alternbative is to use [ADSI]:
$server_list = (Import-Csv -Path 'C:\temp\server3.csv').name
$group = 'Administrators'
$members = foreach ($server in $server_list) {
try {
([ADSI]"WinNT://$server/$group,group").psbase.Invoke('Members') | ForEach-Object {
# test if local or domain
$ADSPath = $_.GetType().InvokeMember("ADSPath", 'GetProperty', $null, $_, $null)
$local = ($ADSPath -like 'WinNT://*')
# get the object name
$name = $_.GetType().InvokeMember('Name', 'GetProperty', $null, $_, $null)
# get object class
$class = $_.GetType().InvokeMember('Class', 'GetProperty', $null, $_, $null)
if ($class -eq 'User') {
if ($local) {
$flag = $_.GetType().InvokeMember("userflags", 'GetProperty', $null, $_, $null)
$enabled = !($flag -band 2) # ADS_UF_ACCOUNTDISABLE
}
else {
$enabled = (Get-ADUser -Filter "SamAccountName -eq '$name'" -ErrorAction SilentlyContinue).Enabled
}
}
else { $enabled = $null }
[PSCustomObject] #{
ComputerName = $server.ToUpper()
Group = $group
Name = $name
ObjectClass = $class
Enabled = $enabled
}
}
}
catch {
Write-Warning $_
}
}
$groups = #($members | Where-Object {$_.ObjectClass -eq 'Group'})
$users = #($members | Where-Object {$_.ObjectClass -eq 'User'})
$result = if ($users.Count) {
# now loop over the user objects
$users | ForEach-Object {
# output an object
[PsCustomObject]#{
'ComputerName' = $_.ComputerName
'Direct Members' = $_.Name
'Account Status' = $_.Enabled
'Group Members' = ($groups.Name | Sort-Object -Unique) -join ';'
}
# clear the $groups here because you only want to list them once per server
$groups = $null
}
}
elseif ($groups.Count) {
# no users, just groups
[PsCustomObject]#{
'ComputerName' = $_.ComputerName
'Direct Members' = $null
'Account Status' = $null
'Group Members' = ($groups.Name | Sort-Object -Unique) -join ';'
}
}
$result | Export-Csv -Path 'c:\temp\local_admins2.csv' -NoTypeInformation
Output from the above when testing
Result using Get-LocalGroupMember:
ComputerName Direct Members Account Status Group Members
------------ -------------- -------------- -------------
MACHINE01 Administrator False Domain Admins;IT-Admins
MACHINE01 LocalAdmin True
MACHINE01 Theo True
Result using WMI:
ComputerName Direct Members Account Status Group Members
------------ -------------- -------------- -------------
MACHINE01 Administrator Degraded Domain Admins;IT-Admins
MACHINE01 Theo OK
MACHINE01 LocalAdmin OK
Result using ADSI:
ComputerName Direct Members Account Status Group Members
------------ -------------- -------------- -------------
MACHINE01 Administrator False Domain Admins;IT-Admins
MACHINE01 Theo True
MACHINE01 LocalAdmin True
I'm trying to export an array of objects to a .csv file, what do I need to do to put everything in the right column with header of a property name.
I've tried selecting properties by select to pipeline
$groups = Get-MsolGroup -All
$results = #()
foreach ($group in $groups) {
$props = #{
'DisplayName' = $group.DisplayName
'GroupType' = $group.GroupType
'Email' = $group.EmailAddress
'MemberCount' = #(Get-MsolGroupMember -GroupObjectId $group.ObjectId).Count
}
New-Object -Type PSObject -Prop $props
$results += $props
}
$results | Export-Csv -Path C:\Users\Tako\Desktop\results.csv -NoTypeInformation
You can use your code like below:
$groups = Get-MsolGroup -All
$output = $groups | ForEach-Object{
[PSCustomObject]#{
"DisplayName" = $_.DisplayName
"GroupType" = $_.GroupType
"Email" = $_.EmailAddress
"MemberCount" = #(Get-MsolGroupMember -GroupObjectId $_.ObjectId).Count
}
}
$output | Export-Csv -Path "F:\temp\1\myresults.csv" -NoTypeInformation
Here is a similar test, just test with Get-AzStorageAccount cmdlet:
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.