Powershell script - Create AD groups from .csv

Tommy_Cooper
Tommy_Cooper used Ask the Experts™
on
All,

Any help with a dumb problem that I am struggling with....

I have this script that works fine to create an AD security group (local).  I want to create a bunch of groups in different OUs and import the values from a .csv

My .csv looks like this:

OU,GroupName,Description,Notes
"ou=Groups,OU=Dev,ou=MyApp,ou=TestEnvironment,dc=MyDomain,dc=com",D_NTFS_AppServer_Import_RO_Local,NTFS RO on Appservers Directory,NTFS RO on Appservers Directory on the following directory: ........ D:\Import
"ou=Groups,OU=UAT,ou=MyApp,ou=TestEnvironment,dc=MyDomain,dc=com",U_NTFS_AppServer_Import_RO_Local,NTFS RO on Appservers Directory,NTFS RO on Appservers Directory on the following directory: ........ D:\Import

Open in new window



This is my script:

 $ADS_GROUP_TYPE_LOCAL_GROUP = 0x00000004
$ADS_GROUP_TYPE_SECURITY_ENABLED = "&H80000000"

$objDomain = New-Object System.DirectoryServices.DirectoryEntry("LDAP://MyDC.MyDomain.com:389/ou=Groups,ou=MyApp,ou=TestEnvironment,dc=MyDomain,dc=com")
$GroupName = "NTFS_import_Local"
$objGroup = $objDomain.Create("group", "CN=" + $GroupName)

$objGroup.Put("groupType", $ADS_GROUP_TYPE_LOCAL_GROUP -bor $ADS_GROUP_TYPE_SECURITY_ENABLED)
$objGroup.Put("sAMAccountName", $GroupName )
$objGroup.Put("Description","NTFS RO on Appservers Import Directory")
$objGroup.Put("Info","NTFS RO on Appservers Import Directory on the following directory: ........ D:\Import")

$objGroup.SetInfo()

Open in new window


How do I modify this script (that works fine creating a single group) so that I can import the values from .csv? Anyone out there who can offer a quick fix?

Cheers
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®

Commented:
Try this. But I would suggest using either the Quest AD cmdlets or MS AD cmdlets. It would make this easier.
$INput = import-csv c:\temp\new_groups.csv
$Input | foreach {

$ADS_GROUP_TYPE_LOCAL_GROUP = 0x00000004
$ADS_GROUP_TYPE_SECURITY_ENABLED = "&H80000000"

$objDomain = New-Object System.DirectoryServices.DirectoryEntry("LDAP://MyDC.MyDomain.com:389/$($_.OU")
$GroupName = $_.GroupName
$objGroup = $objDomain.Create("group", "CN=" + $GroupName)

$objGroup.Put("groupType", $ADS_GROUP_TYPE_LOCAL_GROUP -bor $ADS_GROUP_TYPE_SECURITY_ENABLED)
$objGroup.Put("sAMAccountName", $GroupName )
$objGroup.Put("Description","$($_.Description)")
$objGroup.Put("Info","$($_.Notes)")

$objGroup.SetInfo()

}

Open in new window

Author

Commented:
That is awesome! Exactly what I need. Many thanks.

Just one question though....

1- What would be the advantage here of using Quest cmdlets?  Wouldn't the script be pretty much the same?
2- Am I not using the MS AD cmdlets?

Obviously - you can see my problem with technical stuff - I can't count :)

Commented:
No you are not using the MC cmdlets. Here is an example

new-adgroup TESTGROUP -GroupCategory Security -Path "OU=Groups,DC=Domain,DC=Local"



to get a full list of all cmdlets run these

get-command -module activedirectory

or

get-command -module *Quest*

here are some links

http://technet.microsoft.com/en-us/library/dd378937(WS.10).aspx

http://www.quest.com/powershell/activeroles-server.aspx
How to Generate Services Revenue the Easiest Way

This Tuesday! Learn key insights about modern cyber protection services & gain practical strategies to skyrocket business:

- What it takes to build a cloud service portfolio
- How to determine which services will help your unique business grow
- Various use-cases and examples

Author

Commented:
Grrr!!!!

I swear when I tested this yesterday, it worked fine.

Now I keep getting:

The string starting:
At D:\Scripts\CreateLocalGroup_v1-1.ps1:7 char:6
+ $_.OU <<<< "
is missing the terminator: ".
At D:\Scripts\CreateLocalGroup_v1-1.ps1:7 char:7
+ $_.OU" <<<< 
    + CategoryInfo          : ParserError: (:String) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : TerminatorExpectedAtEndOfString


Any ideas what is causing this?

Commented:
try to change this

$($_.OU

to

$($_.OU)

Author

Commented:
Sorry Ken - No joy with that - I was defo doing that already - Copied the above code to notepad and then into PS ISE

Just had an odd thought though.... gonna try it on another server......

Author

Commented:
No joy I'm afraid :(

Any other ideas?

Author

Commented:
If it's easier - I will use the Quest package (we do not have AD Web Services as we are only running 2003 DCs).

Can I just confirm the following:

1- Creating the variable $Input = import-csv etc. allows me to read the .csv
2- Doing the $Input | foreach { allows me to read each row in the .csv and perform (the following) actions
3- In order to use a value in a row I need to declare it by wrapping the csv column name with "$($_.ColumnName)" including the speech marks?
4- I just need to close with a curly bracket }

Cheers
Tom

 

Commented:
ok, this one should work. I have tested .

your last question, it sounds right it shouldlook like something like this. You will have to put group type and the other attributes you need.


$Input = import-csv c:\temp\groups.csv
$Input | Foreach {

new-qadgroup -name $_.Name -parentcontainer $_.OUName
}
$INput = import-csv c:\temp\groups.csv
$Input | foreach {

$ADS_GROUP_TYPE_LOCAL_GROUP = 0x00000004
$ADS_GROUP_TYPE_SECURITY_ENABLED = '&H80000000'

$objDomain = New-Object System.DirectoryServices.DirectoryEntry("LDAP://devlab.local:389/$($_.OU)")
$GroupName = $_.GroupName
$objGroup = $objDomain.Create("group", "CN=$GroupName")
$objGroup.Put("groupType", $ADS_GROUP_TYPE_LOCAL_GROUP -bor $ADS_GROUP_TYPE_SECURITY_ENABLED)
$objGroup.Put("sAMAccountName", $GroupName )
$objGroup.Put("Description",$($_.Description))
$objGroup.Put("Info",$($_.Notes))

$objGroup.SetInfo()

}

Open in new window

Author

Commented:
Grrrr!!!!!

Minimal changes to the above (I've added my domain controller and that is it! Even moved my input csv to match here) and this is what I'm getting now:


The following exception occurred while retrieving member "Create": "There is no such object on the server.
"
At D:\Systems\Scripts\test.ps1:9 char:12
+ $objGroup = <<<<  $objDomain.Create("group", "CN=$GroupName")
    + CategoryInfo          : NotSpecified: (:) [], ExtendedTypeSystemException
    + FullyQualifiedErrorId : CatchFromBaseGetMember
 
You cannot call a method on a null-valued expression.
At D:\Systems\Scripts\test.ps1:10 char:14
+ $objGroup.Put <<<< ("groupType", $ADS_GROUP_TYPE_LOCAL_GROUP -bor $ADS_GROUP_TYPE_SECURITY_ENABLED)
    + CategoryInfo          : InvalidOperation: (Put:String) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull
 
You cannot call a method on a null-valued expression.
At D:\Systems\Scripts\test.ps1:11 char:14
+ $objGroup.Put <<<< ("sAMAccountName", $GroupName )
    + CategoryInfo          : InvalidOperation: (Put:String) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull
 
You cannot call a method on a null-valued expression.
At D:\Systems\Scripts\test.ps1:12 char:14
+ $objGroup.Put <<<< ("Description",$($_.Description))
    + CategoryInfo          : InvalidOperation: (Put:String) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull
 
You cannot call a method on a null-valued expression.
At D:\Systems\Scripts\test.ps1:13 char:14
+ $objGroup.Put <<<< ("Info",$($_.Notes))
    + CategoryInfo          : InvalidOperation: (Put:String) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull
 
You cannot call a method on a null-valued expression.
At D:\Systems\Scripts\test.ps1:15 char:18
+ $objGroup.SetInfo <<<< ()
    + CategoryInfo          : InvalidOperation: (SetInfo:String) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull
 
=============================

I give up on this one for now - I'm gonna use the Quest cmdlets.  Haven't tested those - will add what works here.

Author

Commented:
Ooops!!! I have an underscore in the real name of an OU (the one I'm testing with).

I think I have it working! :)
Ken - you're a genius!

This is what you get for doing too many things all at once.  Welcome to the world of sysadmins ;)

Author

Commented:
Here's the Quest Script for any who prefer that:

$Input = import-csv c:\Temp\new_groups.csv
$input | foreach {

new-QADGroup -Name $_.GroupName -ParentContainer $_.OU -samAccountName $_.GroupName -Description $_.Description -Notes $_.Notes -GroupType "Security" -GroupScope "DomainLocal"
}


Using the previous example that uses System.DirectoryServices you change the group scope by modifying the values like this:

For a domain local group do...
$ADS_GROUP_TYPE_LOCAL_GROUP = 0x00000004

For a domain global group do...
$ADS_GROUP_TYPE_LOCAL_GROUP = 0x00000002

Author

Commented:
Many thanks Ken. A great help. Sorry if I made you scratch your head!

Commented:
Glad everything is working.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial