Sunday, April 3, 2011

List Local Administrator Group Members on a Server – PowerShell Script

I have updated one of my PowerShell Script  - List Group Members in Active Directory–PowerShell Script – to generate a report and send an email based on number of members in an Administrator group on a server.  I crated this script based on a question posted on the TechNet forum. 

Input – This script reads server names from an input file called Serves.csv

image

Output - It creates an output file called SGroupMemberDetails.csv which contains all server and group information. It also generate an email alert based on number of group members.  You can set this threshold value using $N variable.  

image

Here are the script details

image

Download – You can download the script from www.sivarajan.com.  I have uploaded on this TechNet Script library also. 

Updated script - http://portal.sivarajan.com/2011/10/search-ad-collect-local-admin-group.html

16 comments:

I get this error when I run the script.

Exception calling "Invoke" with "2" argument(s): "Unknown error (0x80005000)"
At C:\Scripts\AdminGrps.ps1:19 char:33
+ $GMembers = $group.psbase.invoke <<<< ("Members")
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException

You cannot call a method on a null-valued expression.
At C:\Scripts\AdminGrps.ps1:20 char:39
+ $GMembers | ForEach-Object {$_.GetType <<<< ().InvokeMember("Name",'GetProperty', $null, $_, $null) | Out-File $GFile -encoding ASCII -append
+ CategoryInfo : InvalidOperation: (GetType:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull

You are getting the “You cannot call a method on a null-valued expression” error. Do you have Server Name in the input file - “C:\Scripts\Servers.csv” ?

Yes there are server names but not the fully qualified domain name.

You don’t need FQDN. You can use NetBIOS name. Do you have “ServerName” as the header in the input file?

Thanks, after adding the ServerName as header it ran successfully.

Good. Thanks for the update.

You can use “get-content” cmdlet with no header. Here is an example:

$SNames = get-content "C:\Scripts\Servers.txt"
foreach($SName in $SNames)
{
$SName
}

http://sivarajan.com/forum/viewthread.php?tid=59

Hi Santosh,
How you doing?

I need you assist. Recently i'm practise on Quest tools for the AD migration. There is any option that....

"the AD user details in bulk or selected users, with this tool we can standardize the usernames like firstname.surname.
Example: vbommidi to ven.bommidi in bulk and all AD account properties.
With this we can import user details to spread sheet, edit the spread sheet and export the spread sheet to AD. we have flexibility to roll back the AD.
We can select by OU, group, Departments and with query script."

Are you planning to rename the user account name during the migration? If so, take a look my following blog:

http://portal.sivarajan.com/2011/07/user-account-migration-and-merging-part.html

You can use an input file to achieve this.

This comment has been removed by the author.

Hi Santosh,
I saved this script in to text file and renamed it in to .ps1 then Created Servers.csv file giving ServerName in header of the file.
Now while running script from powershell, its not giving me any output file.
Server names are there in Servers.csv
What could be the problem

Santhosh, I hope you still monitor this. I am using this script, and getting an error.
New-Object : Constructor not found. Cannot find an appropriate constructor for type System.Net.Mail.Attachment.

I have removed the search AD section, I list the servers manually in servers.csv, it does find the server, shows it is DONE!
Collecting Admin info from server1..........Done!
then immediately errors:
New-Object : Constructor not found. Cannot find an appropriate constructor for type System.Net.Mail.Attach
At C:\scripts\Get-local-admins.ps1:56 char:29
+ $Attachment = New-Object <<<< System.Net.Mail.Attachment($GFile)
+ CategoryInfo : ObjectNotFound: (:) [New-Object], PSArgumentException
+ FullyQualifiedErrorId : CannotFindAppropriateCtor,Microsoft.PowerShell.Commands.NewObjectCommand

Exception calling "Add" with "1" argument(s): "Value cannot be null.
Parameter name: item"
At C:\scripts\Get-local-admins.ps1:57 char:34
+ $Emailmessage.Attachments.Add <<<< ($Attachment)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException

Thanks!

Get Below Error when i run the script ...
=================================================
The term 'Fuction' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spe
lling of the name, or if a path was included, verify that the path is correct and try again.
At D:\AD-Scripts\Scripts\FindCompsADGroupMeb&Email\SearchAD_LocalAdmin_Send_Email.ps1:26 char:9
+ Fuction <<<< Search_LAdmin
+ CategoryInfo : ObjectNotFound: (Fuction:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException


Import-CSV "C:\Scripts\Servers.csv" | ForEach-Object {
$SName = $_.ServerName
Write-host -nonewline "Collecting Admin info from $SName...."
"Server Name - $SName" | Out-File $GFile -encoding ASCII -append
$group = [ADSI]("WinNT://$SName/Administrators,group")
$GMembers = $group.psbase.invoke("Members")
$GMembers | ForEach-Object {$_.GetType().InvokeMember("Name",'GetProperty', $null, $_, $null) | Out-File $GFile -encod
ing ASCII -append}
Write-host "Done!"
$GMembers = ""
}

Searchin AD....5207 Computer Objects Found
The term 'Search_LAdmin' is not recognized as the name of a cmdlet, function, script file, or operable program. Check t
he spelling of the name, or if a path was included, verify that the path is correct and try again.
At D:\AD-Scripts\Scripts\FindCompsADGroupMeb&Email\SearchAD_LocalAdmin_Send_Email.ps1:62 char:14
+ Search_LAdmin <<<<
+ CategoryInfo : ObjectNotFound: (Search_LAdmin:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException

New-Object : Constructor not found. Cannot find an appropriate constructor for type System.Net.Mail.Attachment.
At D:\AD-Scripts\Scripts\FindCompsADGroupMeb&Email\SearchAD_LocalAdmin_Send_Email.ps1:55 char:25
+ $Attachment = New-Object <<<< System.Net.Mail.Attachment($GFile)
+ CategoryInfo : ObjectNotFound: (:) [New-Object], PSArgumentException
+ FullyQualifiedErrorId : CannotFindAppropriateCtor,Microsoft.PowerShell.Commands.NewObjectCommand

Exception calling "Add" with "1" argument(s): "Value cannot be null.
Parameter name: item"
At D:\AD-Scripts\Scripts\FindCompsADGroupMeb&Email\SearchAD_LocalAdmin_Send_Email.ps1:56 char:30
+ $Emailmessage.Attachments.Add <<<< ($Attachment)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException

Exception calling "Send" with "1" argument(s): "Failure sending mail."
At D:\AD-Scripts\Scripts\FindCompsADGroupMeb&Email\SearchAD_LocalAdmin_Send_Email.ps1:59 char:11
+ $SMTP.Send <<<< ($Emailmessage)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException

Hi Santosh,

Sorry to ask as I am sure you are fed up with requests, but can this be modified to show you the domain that a potential users is a member of, if the user is a member of the local admins

Hi,

This is rohit. I am currently trying to add domain global group (Desktopgr) to my local group (Localgr).
Let me pricise this in more details:
I had a machine 2008 server (LDAPCLIENT, ip 10.112.252.222) in a domain (GermanTool.com).
I have a AD (Active directory) server (Vcenter, ip 10.112.252.218).
GermanTool.com is the only domain in the AD server.
The domain has many global group, one of it is 'Desktopgr'.
This group cntains user who can log in to any server in the domain through RDP.

From GUI server managment tool, I can add the Domain Global group (Desktopgr) to a member of computer local group (Localgr)
I have already login to the LDAPCLIENT machine as a domain user 'GermanTool\rohit' and password 'A#007'.


I have removed that group from Localgr. Now I try to write a Powershell script to work the same thing.
I am already logedin as a domain user to the LADPCLIENT machine and both t machine can be pinged from either side and both are in same

domain.


I run the script I wrote but getting error as:

Exception calling "Add" with "1" argument(s): "Access is denied.
"
At C:\script\a.ps1:44 char:20
+ $LocalGroup.Add <<<< ($DomainGroup.Path)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : CatchFromBaseAdapterMethodInvokeTI


The Script is given bellow:

#######################################################################
<#
File: Add2LocalGroup.ps1
Purpose: Example of adding a Domain group to a Local group
Author: Rohit Basu
Date: 12/05/2013
#>



#Get List of Servers from Flat TXT file
$Servers = Get-Content Servers.txt


#GermanTool
#"LDAP://ldap.company.com:389/$($dn)"
#$credn = New-Object -TypeName System.DirectoryServices.DirectoryEntry("LDAP://10.112.252.218:389/GermanTool","rohit","A#007")


#Initaliaze the Domain Group Object
$DomainGroup = [ADSI]"WinNT://10.112.252.218/Desktopgr,Group"

#$DomainGroup = "$credn/Globalgroup,Group"

#Name the LogFile and Initialize it
$LogFile = ".\Logs\ServerLog.txt"
New-Item $LogFile -type file -force

ForEach ($Server in $Servers) #Loop through each server
{
$Server
$Server>>$LogFile


#Get Local Group object
$LocalGroup = [ADSI]"WinNT://$Server/Localgr,Group"

"Hi This is to see Localgroup">>$LogFile
$LocalGroup.Path>>$LogFile
"Hi This is to see Globalgroup">>$LogFile
$DomainGroup.Path>>$LogFile


#Assign DomainGroup to LocalGroup
$LocalGroup.Add($DomainGroup.Path)

#Determine if command was successful
If (!$?) #Add failed
{
$Server + " fail: " + $Error[0]>>$LogFile
"">>$LogFile
}
Else #Add succeeded
{
$Server + " success">>$LogFile
"">>$LogFile
$Server + " success"
}
}
#####################################################

The Servers.txt file contains one Ip: 10.112.252.222

Hello Santhosh, I have got a requirement from auditors, half of which is fulfilled by your script, Many thanks for the same. Could you please help me further?
Requirement:-
1. take input of server names in .csv file
2. give all given server's local administrators group members (with type & domain as well e.g., type as in user/group)
3. take groups one by one and search in AD for it's further members & provide the same(recursive/circular query) in csv format.
example-
server1 > member of "administrators" are following
user1, group1
Take group1 and make a search in AD for it's further members (and so on....) which could be as follows:-
subgrp1, subgrp2, user2
Take subgrp1 and find it's members
Take subgrp2 and find it's members
So kindly help me with this extended requirement (the script should provide a tree like structure as output). Thanks in advance.

Post a Comment

Popular Posts

Share

Twitter Delicious Facebook Digg Stumbleupon Favorites More