With our Users and Computers in place, we can start adding groups. The groups will be based on the Postition ocf the characters in the StarTrek Csv file. I’ve chosen position since many characters can have the same position.
First, let’s look at all the unique Positions in the
Csv file. I’m also using the Series as a Descrption and it’s also used to place the group in the correct OU.
PS > $CsvFile | Select Position, Series -Unique
Position Series
-------- ------
Commanding Officer Star Trek: The Next Generation
First Officer Star Trek: The Next Generation
Chief Engineer Star Trek: The Next Generation
Chief of Security Star Trek: The Next Generation
Chief Medical Officer Star Trek: The Next Generation
Ship's Counselor Star Trek: The Next Generation
Chief Operations Star Trek: The Next Generation
Conn Officer Star Trek: The Next Generation
Transporter Officer Star Trek: The Next Generation
Botanist Star Trek: The Next Generation
Nurse Star Trek: The Next Generation
Bartender Star Trek: The Next Generation
Engineering Officer Star Trek: The Next Generation
Federation Ambassador Star Trek: The Next Generation
Security Officer Star Trek: The Next Generation
Medical Officer Star Trek: The Next Generation
Operations Officer Star Trek: The Next Generation
Commanding Officer Star Trek: Deep Space Nine
First Officer Star Trek: Deep Space Nine
Chief of Security Star Trek: Deep Space Nine
Chief Medical Officer Star Trek: Deep Space Nine
Chief Science Officer Star Trek: Deep Space Nine
Counselor Star Trek: Deep Space Nine
Strategic Operations Officer Star Trek: Deep Space Nine
Chief Operations Star Trek: Deep Space Nine
Civilian Star Trek: Deep Space Nine
Bartender Star Trek: Deep Space Nine
Commanding Officer Star Trek: Voyager
First Officer Star Trek: Voyager
Second Officer Star Trek: Voyager
Chief Engineer Star Trek: Voyager
Medical Officer Star Trek: Voyager
Chief Operations Officer Star Trek: Voyager
Chief Medical Officer Star Trek: Voyager
Chef Star Trek: Voyager
Aeroponics caretaker Star Trek: Voyager
Miscellaneous Star Trek: Voyager
Conn Officer Star Trek: Voyager
Science Star Trek: Voyager
Engineering Officer Star Trek: Voyager
Civilian Star Trek: Voyager
Commanding Officer Star Trek: Enterprise
First Officer Star Trek: Enterprise
Armory Officer Star Trek: Enterprise
Engineering Officer Star Trek: Enterprise
Medical Officer Star Trek: Enterprise
Communications Officer Star Trek: Enterprise
Chief Engineer Star Trek: Enterprise
I’m going to use the first entry “Commanding Officer” to explain how the script works. At first, we have to check if the group already exists. we’ll reuse the checker function that I’ve mentioned in previous blog posts.
function Check-distinguishedName ([string]$Domain, [string]$Group) {
trap { $Script:distinguishedNameDoesntExist = $True ; continue }
.Get-AD.ps1 -Domain $Domain -Group $Group -filter distinguishedName | Out-Null
}
Next we have to build up the groups distinguishedName in order to check it.
PS > $Domain = "powershell.nu"
PS > $Position = "Commanding Officer"
PS > $Series = "Star Trek: The Next Generation"
PS > $distinguishedName = "CN=" + $Position + ",OU=Groups,OU=" + $Series +
>> $Series + ($Domain.Replace(".",",DC=")).Insert(0,",DC=")
PS > $distinguishedName
CN=Commanding Officer,OU=Groups,OU=Star Trek: The Next Generation,DC=powershell,DC=nu
Now that we’ve built up a distinguishedName we can check it through the Check-distinguishedName function. If the group doens’t exist, the variable $distinguishedNameDoesntExist is set to $True, which means that we can go ahead and create the group.
PS > Check-distinguishedName $Domain $distinguishedName
PS > $distinguishedNameDoesntExist
True
Now that we’re sure that the group does’t exist we can create a connection to Active-Directory and create the group. First we’ll set up the connectionstring to the correct OU and create a [adsi] connection.
PS > $Connection = "LDAP://OU=Groups" + $Series.Insert(0,",OU=") +
>> ($Domain.Replace(".",",DC=")).Insert(0,",DC=")
PS > $AD = [adsi] $Connection
Adding the group is quite simple using the Create() method.
PS > $Group = $AD.Create("Group", "CN=$Position")
PS > $Group.SetInfo()
The part that’s not so simple is adding a unique sAMAccountName. Since there’s One Commanding officer for each ship, we will have a total of four different groups with the same name, the distinguishedName doesnt have to be unique as long as its not in the same OU but the sAMAccountName has to be.
First we have to create a sAMAccountName for the group. Since the Group names tend to be quite long, we’ll shorten the groups sAMAccountName through the subString() method if it’s longer than 10 characters. We’ll also remove spaces in the string.
PS > $sAMAccountName = ($Position.replace(" ","")).ToUpper()
PS > if ($sAMAccountName.Length -gt 10) {
$sAMAccountName = $sAMAccountName.SubString(0,9)
}
PS > $sAMAccountName
COMMANDIN
Now that we have a sAMAccountName, we have to check so that it doesn’t exist. again through a checker function.
function Check-sAMAccountName ([string]$Domain, [string]$Group) {
trap { $Script:sAMAccountNameDoesntExist = $True ; continue }
.Get-AD.ps1 -Domain $Domain -Group $Group -filter sAMAccountName | Out-Null
}
If the sAMAccountName exists, we will handle this through a while loop and append an integer at the end.
While ($Script:sAMAccountNameDoesntExist -eq $False) {
$LastChar = $sAMAccountName.SubString($sAMAccountName.Length -1)
if(1..9 -Contains $LastChar) {
$sAMAccountName = ($sAMAccountName.TrimEnd([string]$LastChar)) +
([int]$LastChar + 1)
} else {
$sAMAccountName = $sAMAccountName + 1
}
Check-sAMAccountName -Domain $Domain -Group $sAMAccountName
}
Finally, we can add the additional group information, in this case: sAMAccountName and Description.
$Group.put("Description", $Position)
$Group.put("sAMAccountName", $sAMAccountName)
$Group.setinfo()
Here’s how it looks if we run it in our test environment.
Repeating the script shows that the groups already exist.
and here’s a quick look in dsa.msc
Additionally, let’s look at our Commanding Officer groups. We can do this through the
Get-AD.ps1 script
PS > .Get-AD.ps1 -Domain powershell.nu -Group AllGroups -Property sAMAccountName, cn |
>> Where { $_.cn -match "Commanding Officer" }
sAMAccountName cn
-------------- --
COMMANDIN Commanding Officer
COMMANDIN1 Commanding Officer
COMMANDIN2 Commanding Officer
COMMANDIN3 Commanding Officer
Isn’t it cool how you can take the result of a script and pipe it to the Where-Object CmdLet.
Click Here to Download the Complete Script.
The Get-AD.ps1 script is also required.
Click here to download the Csv File