Getting both computer and user objects from inside security group via powershell - powershell

I can get the user accounts in the group with the following script. But I want to get both computer object and user object in some groups. how can I do it?
Import-Module ActiveDirectory
$groups = Get-ADGroup -Filter "Name -like 'TST*'"
ForEach ($Group in $Groups) {
Get-ADGroupMember -Identity $group |
Get-ADUser -Properties samaccountname,mail,AccountExpires,manager,employeeid,employeetype |
Select-Object samaccountname,mail,employeeid,employeetype,#{l="expiration_date";e={ accountExpiresToString($_.AccountExpires)}},#{n=”Manager Name”;e={(Get-ADuser -identity $_.Manager -properties displayname).DisplayName}} |
Export-CSV -Path "C:tmp\$($group.Name).csv" -NoTypeInformation
}

Just test for the objectclass and deal with accordingly. Use a custom object to construct the output.
Import-Module ActiveDirectory
$groups = Get-ADGroup -Filter "Name -like 'TST*'"
$groups | ForEach-Object {
$Results = Get-ADGroupMember -Identity $_ | ForEach-Object {
#
# For each objectclass you must output the same properties else
# the custom PS object will not construct across object types
# I find this the best way to make it obvious what your code is doing:
#
If ($_.objectclass -eq 'user') {
$ObjDetails = Get-ADUser -Identity $_ -Properties mail,AccountExpires,manager,employeeid,employeetype
$Mail = $ObjDetails.mail
$EmployeeID = $ObjDetails.employeeid
$EmployeeType = $ObjDetails.employeetype
# Unless you're SURE all these fields are populated correctly use Try...Catch or test for the field before assigning
Try {
$ManagerName = (Get-ADuser -identity $ObjDetails.Manager -properties displayname -ErrorAction Stop).DisplayName
}
Catch {
$ManagerName = 'Not found'
}
# Not in a User object, but you must define empty fields
$DNSHostName = ''
}
If ($_.objectclass -eq 'computer') {
$ObjDetails = Get-ADComputer -Identity $_ -Properties DNSHostName
# These fields are not in a Computer object but you must define them
$Mail = ''
$EmployeeID = ''
$EmployeeType = ''
$ManagerName = ''
# This field unique to computer object
$DNSHostName = $ObjDetails.DNSHostName
}
[pscustomobject]#{
SamAccountName = $ObjDetails.SamAccountName
Mail = $Mail
EmployeeID = $EmployeeID
EmployeeType = $EmployeeType
ManagerName = $ManagerName
DNSHostName = $DNSHostName
}
}
# You can then display/export results object
$Results # | Export-CSV -Path "C:\tmp\$($group.Name).csv" -NoTypeInformation
}

Related

A Script that pulls list of AD users and returns manager info

I'm working on script to pull the users' name, email address, and their manager info. I need some help. I have this so far
$requestedUsers = Import-Csv "ADUserlist.csv"
$allUsers = Get-ADUser -filter 'Enabled -eq $true' -Properties name, EmailAddress, Manager
$filterdUsers = $allUsers | Where-Object { $_.SamAccountName -in$requestedUsers.SamAccountName }
$report = foreach ($user in $filterdUsers) {
$managerEmail = $allUsers |
Where-Object DistinguishedName -eq $user.Manager |
Select-Object -ExpandProperty EmailAddress
[PSCustomObject][ordered]#{
DisplayName = $user.Name
EmailAddress = $user.EmailAddress
ManagerEmail = $managerEmail
}
}
$report | Out-GridView
there is no output I don't know where exactly I made a mistake. So I need help if there is any changes to be made.
It should be something like this
Import-Module -name 'ActiveDirectory'
$requestedUsers = Import-Csv -path "ADUserlist.csv" #Full path required
$allUsers = Get-ADUser -filter 'Enabled -eq $true' -Properties 'name', 'EmailAddress', 'Manager'
$filterdUsers = $allUsers | Where-Object { $_.SamAccountName -in $requestedUsers.SamAccountName }
$report = #()
foreach ( $user in $filterdUsers ) {
$managerEmail = ( $allUsers | Where-Object { $_.DistinguishedName -eq $user.Manager } ).EmailAddress
$PSO = [PSCustomObject]#{
DisplayName = $user.Name
EmailAddress = $user.EmailAddress
ManagerEmail = $managerEmail
}
$report += $PSO
}
$report | Out-GridView
If you run this script on AD controller, first you must import module ActiveDirectory.
If you run this script on non AD controller you must use powershell remoting to connect to AD controller and run the script. And of course you must have privilege to run such scripts.

Using a .txt file to find ManagedBy and ManagedBy Email within an AD Group

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}}

Script needs converting to export to CSV

I put together the below, which does the job. However, the output isn't very workable. So I wanted to output this all to a CSV using Export-Csv. Im aware I can do this by moving to a ForEach-Object query, but im not entirely sure how to achieve that.
I have added an attempt to convert it in hopes of a little help. I'm not sure how to specify the variable for each object. For example the first section calls all domains in the forest. How do i use each response in the next piped query? and so on.
$domains = (Get-ADForest).Domains
$controllers = #()
$worked = $false
foreach ($domain in $domains) {
$controller = Get-ADDomainController -Discover -ForceDiscover -DomainName $domain |
Select-Object HostName
$controllers += $controller
}
while (-not $worked) {
try {
foreach ($item in $controllers) {
$value = $item.HostName.Value
Write-Host $value
Write-Host 'Domain Admins'
Get-ADGroupMember -Identity 'Domain Admins' -Server $value |
Get-ADUser -Properties name, samaccountname, Description, EmailAddress |
Where {$_.Enabled -eq $true} |
Format-Table Name, SamAccountName, Description, EmailAddress -AutoSize
}
$worked = $true
} catch {}
}
Conversion Attempt
ForEach-Object{
(Get-ADForest).domains | Get-ADDomainController -Discover -ForceDiscover -DomainName $domain |Select-Object HostName | Get-ADGroupMember -identity 'Domain Admins' -Server $value | Get-ADUser -Properties samaccountname, Description, EmailAddress | Where {$_.Enabled -eq $true}
}| Export-Csv -Path "$HOME/Desktop/DomainAdmins.csv" samaccountname, Description, EmailAddress -AutoSize
If you can get the values from your Get-ADUser call and put them in an object, you can then pipe to convertto-csv.
Here's an example:
$arr = #([pscustomobject]#{name="name"; sam="samaccountname"}, [pscustomobject]#{name="name2"; sam="samaccountname2"});
$arr | ConvertTo-Csv -NoTypeInformation
"name","sam"
"name","samaccountname"
"name2","samaccountname2"
You could get rid of the Format-Table call. The code I've shown in the example pipes and array of objects into the convertto-csv cmdlet. So if Get-ADUser returns objects, you should be able to pipe right into ConvertTo-CSV or Export-Csv -append
The objects are hashtables that are cast to pscustomobjects, it's a nice quick way to illustrate the technique.
The result, as shown, will be csv headers that match your hashtable keys, and the hastable values will be the CSV values.
This is working fine in my local environment and storing the result in D:\Test_File.csv
$domains = (Get-ADForest).Domains
$controllers = #()
$worked = $false
foreach ($domain in $domains) {
$controller = Get-ADDomainController -Discover -ForceDiscover -DomainName $domain | Select-Object HostName
$controllers += $controller
}
while (-not $worked) {
try
{
foreach ($item in $controllers)
{
$value = $item.HostName.Value
Write-Host $value
Write-Host 'Domain Admins'
Get-ADGroupMember -Identity 'Domain Admins' -Server $value |
Get-ADUser -Properties name, samaccountname, Description, EmailAddress |?{$_.Enabled -eq $true}|Export-Csv -Append "D:\Test_File.csv"
}
#$worked = $true
}
catch
{
$Error_Message=$_.Exception.Message
}
}

Get-ADGroup - Group Name, ManagedBy Name and Email

I'm looking to get the the Group Name, Managed By Name and Managed by Email in a PowerShell query similar to this.
Get-ADGroup -filter {Name -like "*Admins" }
The output would look something similar to:
Group Name | Managed By Name | Managed By Email
The issue I'm having is with joining Get-ADGroup and Get-ADUser. In SQL this "join" would happen on get-adgroup.managedby = get-aduser.distinguishedname. I know that's not how it works in Powershell, just thought I'd throw out an example of what I'm trying to do.
Any help would both be welcomed and appreciated.
I see #Mathias R. Jessen beat me to it, but here's what I had:
Get-ADGroup -filter {Name -like "*IT*" } -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}}
You can do it like this:
$Groups = Get-ADGroup -Filter { Name -like "*Admins" } -Properties managedBy,mail
$Groups |Select-Object Name,#{Name='ManagedBy';Expression={(Get-ADUser $_.managedBy).Name}},Mail
The #{} syntax after Select-Object is known as a calculated property.
You could also pipe the groups to ForEach-Object and call Get-ADUser inside the process scriptblock:
Get-ADGroup -Filter {Name -like "*Admins"} -Properties managedBy,mail |ForEach-Object {
# Find the managedBy user
$GroupManager = Get-ADUser -Identity $_.managedBy
# Create a new custom object based on the group properties + managedby user
New-Object psobject -Property #{
Name = $_.Name
ManagedBy = $GroupManager.Name
Email = $_.mail
}
}
I would something do like this:
# Get all groups into a variable
$Group = Get-ADGroup -Filter {Name -like "*Admin*"} | Select-Object -expandProperty Name
foreach ($Groups in $Group){
# Get ManagedBy name for each group (If ManagedBy is empty group wil not be listed)
$User = Get-ADGroup $Groups -Properties * | Select-Object -ExpandProperty ManagedBy
foreach ($Users in $User){
# Get Name and EmailAddress for each User
$Name = Get-ADUser $Users | Select-Object -ExpandProperty Name
$Email = Get-ADUser $Users -Properties * | Select-Object -ExpandProperty EmailAddress
# Write output
Write-Host $Groups "," $Name "," $Email
}
}
Hope this helps.

Find out if a Security Account Manager (SAM) name is a user or a group

edited from original question because the real problem was something unrelated to the question
I got a list of trustees from NTFS permissions and now I want to expand the groups to show membership. If I have a SAM name like MyDomain\name, there's no indication of whether that is a group or not. The Get-ADobject command has an ObjectClass property which will indicate group or user if this is an Active Directory domain object. One can use:
Get-ADObject -filter 'SamAccountName -eq "My Users"' or
$sam = "My Users"
Get-ADObject -filter 'SamAccountName -eq $sam'
Thanks to JPBlanc who had an alternate form of writing that with a script block and some other suggestions.
And thanks, user2142466. That looks like a good suggestion for my original script.
You can use a variavle using :
$sam = "My Users"
Get-ADObject -Filter {(SamAccountName -eq $sam)}
But I agree that using vars in -Filter sometimes results in strange behaviours with vars (see this question), so I prefer to use -LDAPFilter.
Get-ADObject -LDAPFilter "(SamAccountName =$user)"
Be careful the -LDAPFilter use polish notation for the filter, it's a bit disconcerting at the begining, but here, it's the natural way of filtering using the underlaying protocol LDAP.
You can get more information about this syntax in Search Filter Syntax, you can also get corresponding filters in About_ActiveDirectory_Filter.
I am guessing you are getting an array of trustees. (i.e User,Group,user,user,Group). So if you get a group then you want to pull the members from it too?
So I would look to see if it is a group, like how you are doing first and then pulling those members out of it. Add it to an another array which will contain every single user for your NTFS permissions.
$arraytrustees
#Create a blank Array
$NTFSUsers =#()
for each ($object in $arraytrustees){
$ObjectClass = (Get-ADObject -filter {SamAccountName -eq $object}).ObjectClass
If ($ObjectClass -eq "group"){
$AdGroupUsers = (Get-ADGroupMember -identity $object).SamAccountName
$NTFSUsers = $NTFSUsers + $AdGroupUsers
}else{
$NTFSUsers = $NTFSUsers + $ojbect
}
}
I was asked to list all members of the groups, along with their ID, Name, and Description as well, so I added a couple of lines.
cls
$Users = #()
$Groups = #()
$list = Get-Content z:\pcm2.txt
Foreach ($o in $list)
{
$ObjectClass = (Get-ADObject -Filter {SamAccountName -eq $o}).ObjectClass
If ($ObjectClass -eq "User")
{
$U = Get-ADUser -Properties * -Identity $o
$User = "" | Select FullUserName, LoginID, Description
$User.FullUserName = $U.DisplayName
$User.LoginID = $U.SamAccountName
$User.Description = $U.description
$Users += $User
}
Else
{
If ($ObjectClass -eq "Group")
{
$G = Get-ADGroup -Properties * -Identity $o
$GM = Get-ADGroupMember -Identity $G.name -Recursive | Get-ADUser -Properties *
Foreach ($gmember in $GM)
{
$Group = "" | Select GroupName, GroupDescription, GroupMemberName, GroupMemberLoginID, GroupMemberDesc
$Group.GroupName = $G.Name
$Group.GroupDescription = $G.Description
$Group.GroupMemberName = $gmember.Name
$Group.GroupMemberLoginID = $gmember.SamAccountName
$Group.GroupMemberDesc = $gmember.Description
$Groups += $Group
}
}
}
}
$Users | Export-Csv z:\PCMUsers.csv -NoTypeInformation
$Groups | Export-Csv z:\PCMGroups.csv -NoTypeInformation
I received a list and was asked to determine whether the objects were users or group, and I came up with this. It worked!
cls
$Users = #()
$Groups = #()
$list = Get-Content z:\pcm.txt
Foreach ($o in $list)
{
$ObjectClass = (Get-ADObject -Filter {SamAccountName -eq $o}).ObjectClass
If ($ObjectClass -eq "User")
{
$U = Get-ADUser -Properties * -Identity $o
$User = "" | Select FullUserName, LoginID, Description
$User.FullUserName = $U.DisplayName
$User.LoginID = $U.SamAccountName
$User.Description = $U.description
$Users += $User
}
Else
{
If ($ObjectClass -eq "Group")
{
$G = Get-ADGroup -Properties * -Identity $o
$Group = "" | Select GroupName, Description
$Group.GroupName = $G.Name
$Group.Description = $G.Description
$Groups += $Group
}
}
}
$Users | Export-Csv z:\Users.csv -NoTypeInformation
$Groups | Export-Csv z:\Groups.csv -NoTypeInformation