Archive

Posts Tagged ‘Active-Directory’

Adding HomeFolder Through PowerShell

April 27th, 2009 Niklas Goude No comments

It’s been some time since my last post now, had alot of things to do at work, but now I’m back OnTrack with my blogging.

Last time we checked out how to add group membership through PowerShell, so now we should have a nice test environment in place, based on Star Trek.

In this post, we are going to script up Users homefolders and add each user to the correct folder. We’ll accomplish this through the following four steps:

  • Add a Share on the Server
  • Add unique folders for all Users
  • Add unique Permissions to the FOlders
  • Edit the User Objects in Active-Direcroty

I’m also going to re-use a script I wrote a couple of months ago, but we’ll get back to that.

Let’s start off by creating a Share. This can be done through the Create() method in the WMI class Win32_Share. The Win32_Share is well described in MSDN.

Since we want to make the script re-usable, we should check if the Share already exists. This is a simple procedure through PowerShell.


PS > $Share = "C:\Share"
PS > $ShareName = "Share"
PS > if ((gwmi Win32_Share | Where { $_.Path -eq $Share}).Path -eq $Share ) {
>>  Write-Host "Share: $ShareName already exists." -ForeGroundColor Red
>>  }

If the Share Already exists “Share: Share already exists” will be prompted, if not we can continue with the script.

Now that we know that the share doesn’t exist, we have to check that the folder exists, and if not, create the folder.


PS > if (!(Test-Path $Share)) {
>>  New-Item -Path $Share -type directory | Out-Null
>>  }

and finally, we can create our Share through WMI. Setting type to 0 creates a Disk Drive Share.


PS > $CreateShare = [wmiclass]"Win32_Share"
PS > $CreateShare.Create($Share,$ShareName,$Type) | Out-Null

add-stshare02

Now that the share is up and running, we can create our HomeFolders. First we set up our HomeDrive and HomeFolder variables, we’ll also set up a User for the example.


PS > $Share = "Share"
PS > $User = "jeapic"
PS > $HomeDrive = "H"
PS > $HomeDirectory = "\\" + $env:COMPUTERNAME + "\" + $Share + "\" + $User

Since the script runs on the server where the Share is created, we can use the environment variable to retrieve the computername.

Next, we want to check if the user already has the homedrive and homedirectory set. We can use the Get-AD.ps1 script for this. I’m also adding the -ToObject switch since i want to use the object later on.


PS > $GetUser = ./Get-AD.ps1 -Domain $Domain -User $User -Filter sAMAccountName -ToObject
PS > if ($GetUser.homeDirectory -match $HomeDirecory -AND $GetUser.homeDrive -match $HomeDrive) {
>> Write-Host "User: $User HomeDrive Already Set" -ForeGroundColor Yellow
>> }

If the User already has the HomeDrive set, we won’t continue, if not, we can go ahead and add it. But before connecting the User to the folder, want to create and give the user FullControl of his HomeFolder. Here we can use the Set-FolderPermission.ps1 script


PS > $Domain = "powershell.nu"
PS > $DomainUser = $Domain + "\" + $User
PS > ./Set-FolderPermission.ps1 -Path $HomeDirectory -Access $DomainUser -Permission FullControl

The Set-FolderPermission.ps1 both created the folder and set up the permissions for us, now all we have to do is set HomeDrive and HomeDirectory to the User Object.


PS > $GetUser.Put("homeDirectory",$HomeDirectory)
PS > $GetUser.Put("homeDrive",$HomeDrive)
PS > $GetUser.SetInfo()

And that’s it.

Running the script Doesn’t require the Star Trek Csv file used in the other examples, it does however require you to loop through each Users that you want to add Homefolders to. In order to get a list of all Users within an OU you can use the Get-AD.ps1 script, as shown below.


PS > ./Get-AD.ps1 -domain "LDAP://OU=Star Trek: The Next Generation,DC=powershell,DC=nu" -User AllUsers -Property sAMAccountName | ForEach {
>> ./Add-STHomeFolder.ps1 -Domain powershell.nu -User $_.sAMAccountName -Share Share -HomeDrive H
>> }

All I have to do now is change the LDAP path above and repeat the ForEach on each OU that contains Users that I want to add a HomeFolder to.

Here are a couple of screenshots on running the scripts:

add-sthomefolder

add-sthomefolder02

Click Here to Download the Add-STShare.ps1 Script.

Click Here to Download the Add-STHomeFolder.ps1 Script.

The Get-AD.ps1 script is also required.

Here’s the Set-Foldepermission.ps1 Script that’s also required.

Rating 3.00 out of 5
[?]

Adding Group Membership Through PowerShell

April 16th, 2009 Niklas Goude No comments

Time to add some members to our groups. Following the steps in the previous posts, we should now have a couple of Users, groups and computers in our test environment. Group Names are based on the Character position in the Star Trek Csv file so now, all we have to do is match up the Characters with their Positions.

Starting of, Let’s collect the information we need from the Csv File.

There are 68 Characters in the file so I’m only going to select the first one in the eample below.


PS > $CsvFile = Import-Csv StarTrek.csv
PS > ($CsvFile | Select Character, Position, Series)[0] | fl


Character : Jean-Luc Picard
Position  : Commanding Officer
Series    : Star Trek: The Next Generation

What we want to do now is add each member to the correct group. Let’s take the first User, Captain Picard, as an example and see how this is done.

Since there are 4 different Commanding Officer groups, we want to make sure that we connect to the correct one. We know which Starship (OU) the Captain is in since and we have that information in the Csv file so we can use this in combination with the Get-AD.ps1 script.

First we have get the OU:s distinguishedName.


PS > $Domain = "powershell.nu"
PS > $Series = "Star Trek: The Next Generation"
PS > $OU = ./Get-AD.ps1 -Domain $Domain -OU $Series -property distinguishedName
PS > $OU


distinguishedName
-----------------
OU=Star Trek: The Next Generation,DC=powershell,DC=nu


PS > $DomainConnection = "LDAP://" + [string]$OU.distinguishedName
PS > $DomainConnection

LDAP://OU=Star Trek: The Next Generation,DC=powershell,DC=nu

Now that we have the connectionstring, we can use this to narrow down the search in the Get-AD.ps1 script. By typing -Domain followed by an OU:s distinguishedName forces the script to only search within the OU structure.


PS > $Character = "Jean-Luc Picard"
PS > $User = ./Get-AD.ps1 -Domain $DomainConnection -User $Character -property distinguishedName, Name
PS > $UserConnection = "LDAP://" + [string]$User.distinguishedName
PS > $UserConnection

LDAP://CN=Jean-Luc Picard,OU=Users,OU=Star Trek: The Next Generation,DC=powershell,DC=nu

PS > $UserdistinguishedName = [string]$User.distinguishedName
PS > $UserdistinguishedName

CN=Jean-Luc Picard,OU=Users,OU=Star Trek: The Next Generation,DC=powershell,DC=nu

So why bother to create one variable holding the distinguishedName and one holding the LDAP connection string ?? well, we’ll get to that in a while but first we need a connection to the group as well.


PS > $Position = "Commanding Officer"
PS > $Group = ./Get-AD.ps1 -Domain $DomainConnection -Group $Position -ToObject
PS > $Group | Format-List *


objectClass          : {top, group}
cn                   : {Commanding Officer}
description          : {Commanding Officer}
distinguishedName    : {CN=Commanding Officer,OU=Groups,OU...
instanceType         : {4}
whenCreated          : {4/15/2009 5:09:08 PM}
whenChanged          : {4/15/2009 5:09:08 PM}
uSNCreated           : {System.__ComObject}
uSNChanged           : {System.__ComObject}
name                 : {Commanding Officer}
objectGUID           : {74 231 168 162 107 193 157 74 161
objectSid            : {1 5 0 0 0 0 0 5 21 0 0 0 50 71 101...
sAMAccountName       : {COMMANDIN}
sAMAccountType       : {268435456}
groupType            : {-2147483646}
objectCategory       : {CN=Group,CN=Schema,CN=Configuratio...
nTSecurityDescriptor : {System.__ComObject}

Now that we got the correct group, all we have to do is make a simple check so that the Captain isn’t already member of the group and if not, add him to it. Here’s where the distinguishedName and LDAP string come in handy.


PS > if ($Group.member -Contains $UserdistinguishedName) {
Write-Host “The Captain is already member”
} else {
$Group.Add($UserConnection)
}

Now let's how the complete script would handle this.

add-stmember01

Repeating the script tells us that the Characters are already members of the groups.

add-stmember02

And here's a quick check in the Active-Directory snapin.

add-stmember03

Click Here to Download the Complete Script.

The Get-AD.ps1 script is also required.

Click here to download the Csv File

Rating 3.00 out of 5
[?]

Adding Groups Through PowerShell

April 15th, 2009 Niklas Goude 1 comment

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.

add-stgroup01

Repeating the script shows that the groups already exist.

add-stgroup02

and here’s a quick look in dsa.msc

add-stgroup03

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

Rating 3.00 out of 5
[?]

Adding Computers through PowerShell

April 13th, 2009 Niklas Goude 2 comments

Now let’s add a couple of computers to our test environment. The Computer Names are based on the Starships from the Csv file. Since there are alot of characters but not that many different ships we need to get a unique list of ships. We also wnat the Series, Location and Registry values.


PS > $CsvFile = Import-Csv StarTrek.csv
PS > $CsvFile | Select Series, Starship, Location, Registry -unique | fl


Series   : Star Trek: The Next Generation
Starship : USS Enterprise (NCC-1701-D)
Location : Alpha Quadrant
Registry : NCC-1701-D

Series   : Star Trek: Deep Space Nine
Starship : Deep Space Nine
Location : Alpha Quadrant
Registry : DS9

Series   : Star Trek: Voyager
Starship : USS Voyager (NCC-74656)
Location : Delta Quadrant
Registry : NCC-74656

Series   : Star Trek: Enterprise
Starship : Enterprise (NX-01)
Location : Alpha Quadrant
Registry : NX-01

Let’s walk through how the script handles the first Starship. At first we have to check if the Computer exists, We’ll use a checker function that checks if the Computer doesn’t exist.


function Check-distinguishedName ([string]$Domain, [string]$Computer) {

   trap {  $Script:distinguishedNameDoesntExist = $True ; continue }
   .Get-AD.ps1 -Domain $Domain -Computer $Computer -filter distinguishedName | Out-Null
}

Next we have to check create a variable holding a distinguishedName and check if it exists or not.


PS > $Starship = "USS Enterprise (NCC-1701-D)"
PS > $Domain = "powershell.nu"
PS > $distinguishedName = "CN=" + $Starship + ",OU=Computers,OU=" + $Series + ($Domain.Replace(".",",DC=")).Insert(0,",DC=")

Now we can run the function.


PS > Check-distinguishedName -Domain $Domain -Computer $distinguishedName

Now that we’ve checked the distinguisehdName we can connect to AD and start adding our Computer.


PS > $Connection = "LDAP://OU=Computers" + $Series.Insert(0,",OU=") + ($Domain.Replace(".",",DC=")).Insert(0,",DC=")

PS > $AD = [adsi] $Connection

PS > $Computer = $AD.Create("Computer", "CN=$Starship")
PS > $Computer.SetInfo()

Now for the additional information. We might want to change the sAMAccountName from the default name generated by AD. We also want to check that the name we choose doesn’t exist so we’ll use yet another check function.


function Check-sAMAccountName ([string]$Domain, [string]$Computer) {

   trap {  $Script:sAMAccountNameDoesntExist = $True ; continue }
   .Get-AD.ps1 -Domain $Domain -Computer $Computer -filter sAMAccountName | Out-Null
}

We’ll base the sAMAccountName on the Ships Registry information. In this case, the registry is NCC-1701-D


PS > $sAMAccountName = ($Registry).ToUpper()

PS > Check-sAMAccountName -Domain $Domain -Computer $sAMAccountName

If the sAMAccountName doesn’t exist the script will use it on the Computer object. If it does exist, theres a while loop that loops through and appends a digit in order to get a unique sAMAccountName. Here’s an example on the where loop.


While ($Script:sAMAccountNameDoesntExist -eq $False) {

   # Create New sAMAccountName

   $LastChar = $sAMAccountName.SubString($sAMAccountName.Length -1)

    if(1..9 -Contains $LastChar) {

    $sAMAccountName = $sAMAccountName.SubString(0,$sAMAccountName.Length -1) + ([int]$LastChar + 1)

   } else {

    $sAMAccountName = $sAMAccountName.SubString(0,$sAMAccountName.Length -1) + 1
   }

   Check-sAMAccountName -Domain $Domain -Computer $sAMAccountName
}

The final Steps of the script add the additional information and enables the computer.


PS > $Computer.put("sAMAccountName", $sAMAccountName)
PS > $Computer.put("Location", $Location)
PS > $Computer.put("Description", $Starship)
PS > $Computer.setinfo()

PS > $Computer.PsBase.InvokeSet("AccountDisabled", $False)
PS > $Computer.SetInfo()

Now let’s run the script in our test environment.

add-stcomputer011

If we repeat the script it’ll tell us that the computers already exist.

add-stcomputer02

If we check in dsa.msc snap-in we can see that the computer objects have been created.

add-stcomputer03

and finally, if we want to retrieve the information through PowerShell, we can use the Get-AD.ps1 script.


PS > .Get-AD.ps1 -Domain powershell.nu -Computer "Uss Enterprise (NCC-1701-D)"


objectClass          : top person organizationalPerson user computer
cn                   : USS Enterprise (NCC-1701-D)
description          : USS Enterprise (NCC-1701-D)
distinguishedName    : CN=USS Enterprise (NCC-1701-D),OU=Computers,OU=Star Trek
                       u
instanceType         : 4
whenCreated          : 4/13/2009 7:19:11 PM
whenChanged          : 4/13/2009 7:19:11 PM
uSNCreated           : System.__ComObject
uSNChanged           : System.__ComObject
name                 : USS Enterprise (NCC-1701-D)
objectGUID           : 31 54 123 251 207 232 62 72 153 101 238 77 71 88 19 27
userAccountControl   : 544
badPwdCount          : 0
codePage             : 0
countryCode          : 0
badPasswordTime      : System.__ComObject
lastLogoff           : System.__ComObject
lastLogon            : System.__ComObject
pwdLastSet           : System.__ComObject
primaryGroupID       : 513
objectSid            : 1 5 0 0 0 0 0 5 21 0 0 0 50 71 101 4 93 25 58 165 36 24
accountExpires       : System.__ComObject
logonCount           : 0
sAMAccountName       : NCC-1701-D
location             : Alpha Quadrant
sAMAccountType       : 805306368
objectCategory       : CN=Computer,CN=Schema,CN=Configuration,DC=powershell,DC=
nTSecurityDescriptor : System.__ComObject

Click Here to Download the Complete Script.

The Get-AD.ps1 script is also required.

Click here to download the Csv File

Rating 3.00 out of 5
[?]

Adding Users through PowerShell

April 13th, 2009 Niklas Goude 2 comments

Now that we have our OU structure in place, we can start adding users.

Since the Users contain alot of information we’ll go ahead and use the whole csv file.

Let’s take a quick look at the first entry in the Csv file:


PS > (Import-Csv StarTrek.csv)[0]


Character  : Jean-Luc Picard
Position   : Commanding Officer
Rank       : Captain
Department : Main Bridge
Species    : Human
Starship   : USS Enterprise (NCC-1701-D)
Class      : Galaxy
Registry   : NCC-1701-D
Series     : Star Trek: The Next Generation
Location   : Alpha Quadrant

Let’s start adding the Users to the Domain. First off, we need to build up a connectionstring. In the script, I build it based on


PS > $Series = "Star Trek: The Next Generation"
PS > $Domain = "powershell.nu"
PS > $Connection = $Series.Insert(0,"LDAP://OU=Users,OU=") + ($Domain.Replace(".",",DC=")).Insert(0,",DC=")
PS > $Connection

LDAP://OU=Users,OU=Star Trek: The Next Generation,DC=powershell,DC=nu

Now for the Fun part. In the Csv file, some Characters don’t have any surNames and some have middle names, so this is something I have to consider in the script. Thanks to the Power of PowerShell it doesn’t have to get to complex.

Step one is Checking the characters name. I use the Split() method to determine if the user has a SurName or any Middle Names.


PS > $Character = "Jean-Luc Picard"
PS > $CharacterName = $Character.Split(" ")
PS > $CharacterName

Jean-Luc
Picard

In this example, Jean-Luc would be the givenName and Picard the surName. I control this in the script through a if else statement that checks if the $CharacterName contains 1 row or more.


if (($CharacterName.Count) -le 1) {

} else {

}

In the case of Jean-Luc Picard, the Name contains more than 1 row, so let’s move on to the else statement.

The else statement starts of by setting up giveName and SurName. the $giveName variable contain all names except the last one. So if we would use Charles Trip Tucker instead of Picard, the givenName would be “Charles Trip” and surName would be set to “Tucker”.


PS > $givenName = $CharacterName[0..($CharacterName.Count -2)]
PS > $sn = $CharacterName[($CharacterName.Count -1)]
PS > $givenName

Jean-Luc

PS > $sn

Picard

Now that we’ve sliced and diced the characters name, we do an additional check to see if the character name will fit the sAMAccountName structure decided in Part 1.0.0 (First 3 from giveName and first 3 from surName).


if ($givenName.Length -lt 3 -AND $sn.Length -lt 3) {

   $Tempcn = $givenName + $sn
   $AddNum = 3 - $Tempcn.Length

   # Build Last Part Of cn

   for ($i = 0; $i -lt ($AddNum -1); $i ++) { $AddTocn += "0" }
   $AddTocn += "1"

   [string]$sAMAccountName = ($Tempcn).ToLower() + $Addtocn
   $cn = $givenName

   # Set Checker to Null

   $AddTocn = $Null

} elseif ($givenName.Length -lt 3 -OR $sn.Length -lt 3) {

   $Tempcn = $givenName + $sn

   [string]$sAMAccountName = ($Tempcn.SubString(0,6)).ToLower()
   $cn = $givenName + " " + $sn

} else {

   [string]$sAMAccountName = ($givenName.SubString(0,3)).ToLower() + ($sn.SubString(0,3)).ToLower()
   $cn = $givenName + " " + $sn
}

The if elseif else statement goes through the characters name and checks if it falls within parameters. If it does not, a number will be added at the end of the Name to compensate. The elseif statement takes care of users where givenName or surName has less than 3 characters and compensates this.

Here’s how Jean-Luc Picard is set up now:


PS > $givenName

Jean-Luc

PS > $sn

Picard

PS > $sAMAccountName

jeapic

PS > $cn

Jean-Luc Picard

Now that we have the sAMAccountName in place we have to check if the sAMAccountName is taken by some other User. We can do this by creating a function that looks up the users sAMAccountName from the Get-AD.ps1 script.


function Check-sAMAccountName ([string]$Domain, [string]$User) {

   trap {  $Script:sAMAccountNameDoesntExist = $True ; continue }
   .Get-AD.ps1 -Domain $Domain -User $User -Filter sAMAccountName | Out-Null
}

If the UserName already exists the script uses a While loop to determine how many sAMAccountNames are taken and when an empty sAMAccountName is found it will be used.


if ($sAMAccountNameDoesntExist -eq $True) {

} else {

   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 -User $sAMAccountName
   }
}

If jeapic already exists the number 1 will be appended to his sAMAccountName, and if jeapic1 already exists 1+1 ( 2) would be appended instead. Note that doing this sets the sAMAccountName to 7 characters instead of 6. If you always want to use 6 chars you could substring() out characters 1 to 5 ( 0,4 ) and build up a sAMAccountName containing only 6 characters.

Now that we have a unique sAMAccountName, we want to check the Users distinguishedName. If the distinguishedName already exists then we will not Add the User, since he already exists. If not, we will go ahead and add our user. The distinguishedName check function is basically the same as the sAMAccountName checker, only differens is that it filters on distinguishedName instead.


function Check-distinguishedName ([string]$Domain, [string]$User) {
   trap {  $Script:distinguishedNameDoesntExist = $True ; continue }
   .Get-AD.ps1 -Domain $Domain -User $User -filter distinguishedName | Out-Null
}

The function takes distinguishedName as an argument, so we have to build up this string. The OU structure was set up in Part 1.1.1 so the User should be in the following OU: “OU=Users,OU=Star Trek: The Next Generation,DC=powershell,DC=nu”.


$distinguishedName = "CN=" + $cn + ",OU=Users,OU=" + $Series + ($Domain.Replace(".",",DC=")).Insert(0,",DC=")

If the disyinguishedName doesnt exist, we can go ahead and create the User. For safety reasons, we generate a secure password for each user that we create and store the passwords in a password file. We could obviously set all Passwords to “Password1″ but that wouldn’t be fun.

Here’s a simple password generator that I’ve created. Using the System.Random Class to generate random numbers.


function Generate-Password {

  $Random = New-Object System.Random

  # Two Upper Case Characters

  [string]$Password += [char]$Random.Next(49,57)
  [string]$Password += [char]$Random.Next(65,72)

  # Two LowerCase Characters

  [string]$Password += [char]$Random.Next(97,107)
  [string]$Password += [char]$Random.Next(109,122)

  # One Special Char

  [string]$Password += [char]$Random.Next(36,43)

  # Two UpperCase Characters

  [string]$Password += [char]$Random.Next(65,72)
  [string]$Password += [char]$Random.Next(80,91)

  # One LowerCase

  [string]$Password += [char]$Random.Next(97,107)

  $Password
  $Password = $Null
}

Why not make it a a shorter script and randomize [char]49 to [char]122? Well, if I randomize any character from [char]49 to [char]122 i might get an “O” and numeric “0″, or “l”,”I” or numeric “1″. Users might find it hard to differentiate an O from an 0 so I’ve excluded Characters that look alike in the function. Also, if I use a for statement and loop through [char]$Random.Next(49,122) eight times, it’s not certain that i get an acceptable Password, i might all uppercase characters and AD wouldn’t accept that.

Now that we have a Password generator we can create our User.


PS > $Description = $Position + " (" + $Species + ")"
PS > $Title = $Rank
PS > $physicalDeliveryOfficeName = $Starship
PS > $userPrincipalName = $sAMAccountName + "@" + $Domain
PS > $mail = ([string]$Character).Replace(" ",".") + "@" + $Domain

PS > [string]$Password = Generate-Password

PS > $OU = [adsi] $Connection
PS > $User = $OU.Create("user", "cn=$cn")
PS > $User.Put("sAMAccountName", $sAMAccountName)
PS > $User.Put("userPrincipalName", $userPrincipalName)
PS > $User.Put("DisplayName", $cn)
PS > $User.Put("givenName", $givenName)
PS > $User.Put("sn", $sn)
PS > $User.Put("Description", $Description)
PS > $User.Put("l", $Starship)
PS > $User.Put("streetAddress",$Location)
PS > $User.Put("physicalDeliveryOfficeName", $physicalDeliveryOfficeName)
PS > $User.Put("Title", $Title)
PS > $User.Put("Department", $Department)
PS > $User.Put("Company", $Starship)
PS > $User.Put("mail", $mail)
PS > $User.SetInfo()

PS > $User.PsBase.Invoke("SetPassword", $Password)
PS > $User.PsBase.InvokeSet("AccountDisabled", $false)
PS > $User.SetInfo()

Now all i have to do is Collect the Generated Password in a file.


PS > $FileName = "PasswordList " + (get-date -uformat "%Y-%m-%d") + ".txt"
PS > "$sAMAccountName,$cn,$Password" | Add-Content $FileName

Running the script in our test environment would look something like this:

add-stuser01

If we repeat the script, the checker function fould tell us that the Users already exist:

add-stuser02

Now for a peek in Active-Directory snap-in dsa.msc

add-stuser03

And Finally, let’s look closer on Captain Jean-Luc Picard and see if the Values specified in the script are set.

add-stuser04

And here’s an example on the Autogenerated Password List.

Click Here to Download the Complete Script.

The Get-AD.ps1 script is also required.

Click here to download the Csv File

Rating 3.00 out of 5
[?]

Adding Ou Structure using Powershell

April 13th, 2009 Niklas Goude No comments

Starting of, we need to set up a couple of OrganizationalUnits in our test environment. Following the structure set up in Part 1.1.0:

Organizational Unit Structure

  • ou = Series
  • l = Location
  • Description = Starship
  • Child OU: Computers
  • Child OU: Groups
  • Child OU: Users

The first step in scripting up a OU structure from based on the StarTrek Csv file is to collect the information through PowerShell. Since the Csv file contains 68 rows of information and 10 different columns, we want to retrieve only information that we need to create a Csv Structure. The columns of interest are: Series, Starship and Location. Using Import-Csv in combination With Select-Object gets all entries matching this.


PS > Import-Csv StarTrek.csv | Select-Object Series, Starship, Location


Series                         Starship                    Location
------                         --------                    --------
Star Trek: The Next Generation USS Enterprise (NCC-1701-D) Alpha Quadrant
Star Trek: The Next Generation USS Enterprise (NCC-1701-D) Alpha Quadrant
Star Trek: The Next Generation USS Enterprise (NCC-1701-D) Alpha Quadrant
Star Trek: The Next Generation USS Enterprise (NCC-1701-D) Alpha Quadrant
Star Trek: The Next Generation USS Enterprise (NCC-1701-D) Alpha Quadrant
Star Trek: The Next Generation USS Enterprise (NCC-1701-D) Alpha Quadrant
Star Trek: The Next Generation USS Enterprise (NCC-1701-D) Alpha Quadrant
Star Trek: The Next Generation USS Enterprise (NCC-1701-D) Alpha Quadrant
Star Trek: The Next Generation USS Enterprise (NCC-1701-D) Alpha Quadrant
Star Trek: The Next Generation USS Enterprise (NCC-1701-D) Alpha Quadrant
Star Trek: The Next Generation USS Enterprise (NCC-1701-D) Alpha Quadrant
Star Trek: The Next Generation USS Enterprise (NCC-1701-D) Alpha Quadrant
Star Trek: The Next Generation USS Enterprise (NCC-1701-D) Alpha Quadrant

Now we,ve managed to retrieve the specified columns and rows. Next we need to narrrow the list down to only unique entries. We can achieve this through the -Unique SwitchParameter.


PS > Import-Csv .StarTrek.csv | Select-Object Series, Starship, Location -Unique


Series                         Starship                    Location
------                         --------                    --------
Star Trek: The Next Generation USS Enterprise (NCC-1701-D) Alpha Quadrant
Star Trek: Deep Space Nine     Deep Space Nine             Alpha Quadrant
Star Trek: Voyager             USS Voyager (NCC-74656)     Delta Quadrant
Star Trek: Enterprise          Enterprise (NX-01)          Alpha Quadrant

Now that we’ve narrowed down our list, we can start creating the OU structure.

The OU:s Name should be “Series”, so the structure that we’re looking for is:

  • Star Trek: The Next Generation
  • Star Trek: Deep Space Nine
  • Star Trek: Voyager
  • Star Trek: Enterprise

But how do we know that these OU:s dont already exist in our Environment ? We have to check this in some way so we need a checker that makes sure that the OU doesn’t exist. This is an excellent oppurtunity to use the Get-AD.ps1 script that I wrote. The checker is rather simple, it consists of a function that sets a variable to $True if the OU does not exist.


function Check-distinguishedName ([string]$Domain, [string]$OU) {

	trap {  $Script:distinguishedNameDoesntExist = $True ; continue }
	.\Get-AD.ps1 -Domain $Domain -OU $OU -Filter distinguishedName | Out-Null
}

The Variable $Script:distinguishedNameDoesntExist is set to $True if we test the function on a non existing OU. Here’s an example on how it works:


PS > Check-distinguishedName -Domain powershell.nu -OU "OU=Domain Controllers,DC=powershell,DC=nu"
PS > $distinguishedNameDoesntExist

Since Domain Controllers Exist, the variable $distinguishedNameDoesntExist is not set to anything. Running the same function on a OU that does not exist:


PS > Check-distinguishedName -Domain powershell.nu -OU "OU=Non Existing OU,DC=powershell,DC=nu"
PS > $distinguishedNameDoesntExist

True


PS > $distinguishedNameDoesntExist = $Null

This time the variable $distinguishedNameDoesntExist was set to True, which means that the OU does not exist and it’s available for creation. I also set the Variable to $Null so that i can reuse the function.

Moving on. If the $distinguishedNameDoesntExist equals $True we can start building up the OU Structure. In the script, there’s a paramter called -Domain which takes the domain name as an argument. In my examples I’m going to use the powershell.nu domain. Setting this as an argument is similar to creating a Variable holding the domain name:


PS > $Domain = "powershell.nu
PS > $Domain

powershell.nu

With this information we can create a Connection string that we can use when connecting to Active-Directory. We can make use of the methods() withing System.String to alter the string as we want it. I’m using Replace() and Insert() to get the result I want:


PS > $Connection = ($Domain.Replace(".",",DC=")).Insert(0,"LDAP://DC=")

PS > $AD = [adsi] $Connection
PS > $AD


distinguishedName
-----------------
{DC=powershell,DC=nu}

Now that we’ve set up a connection we can start creating an OU. It’s pretty straight forward, nothing fancy here:


PS > $OU = $AD.Create("OrganizationalUnit", "ou=$Series")
PS > $OU.SetInfo()

PS > $OU.put("l", $Location)
PS > $OU.put("Description", $Starship)
PS > $OU.setinfo()

When creating Child OU:s, we need to alter the Connection string so that we connect to the OU that we’ve just created, here’s an example on doing that:


$NewConnection = "LDAP://OU=" + $Series + ($Domain.Replace(".",",DC=")).Insert(0,",DC=")
$NewOU = [adsi]$NewConnection

Now we can start creating Child OU:s that are structured after our purpose:


$Users = $NewOU.Create("OrganizationalUnit", "ou=Users")
$Users.SetInfo()

$Users.put("l", $Location)
$Users.put("Description", $Starship)
$Users.setinfo()

This describes the steps that I’ve set up in the Script. Running the script in the test environment would look like this:

add-stou01

If i repeat the script, the Check function finds that the top OU:s already exists and the following is returned to the host:

add-stou02

Finally, taking a peek in dsa.msc.

add-stou03

Click Here to Download the Complete Script.

The Get-AD.ps1 script is also required.

Click here to download the Csv File

Rating 3.00 out of 5
[?]

Scripting up an Active-Directory Test Environment through PowerShell

April 11th, 2009 Niklas Goude No comments

The first step in building up a Test Environment is analyzing the data that we have to work with. In this case, the Star Trek Reference Csv file.

Since the Csv file doesn’t say sAMAccountName or organizationalUnit I’ve to set up a routine for handling this. Based on the information, I’ve set up the following rules:

User Information

  • Common Name = Character Name
  • sAMAccountName = First 3 Characters from givenName and surName
  • userPrincipalName = sAMAccountName and Domain
  • DisplayName = Character Name
  • givenName = First part of Character Name
  • surName = Last part of Character Name
  • Description = Postition + Species
  • l = Starship
  • streetAddress = Location
  • physicalDeliveryOfficeName = Starship
  • Title = Rank
  • Department = Department
  • Company = Starship
  • mail = CharacterName and Domain

Computer Information

  • Common Name = Starship
  • sAMAccountName = Registry
  • Location = Location
  • Description = Starship

Group Information

  • Common Name = Position
  • Description = Position
  • sAMAccountName = Position

Group MemberShip

  • Members = Based on Users Position

Organizational Unit Structure

  • ou = Series
  • l = Location
  • Description = Starship
  • Child OU: Computers
  • Child OU: Groups
  • Child OU: Users

Users HomeFolder

  • HomeFolder = Based on Users sAMAccountName and a defined Path

Most of these steps may seem trivial and easy to script up based on a Csv file, but there are numerous steps to consider, for example: some Characters, such as T’pol and Phlox don’t have any surnames (at least not any surnames recorded in the Vulcan Database) so these names must be handled in the script. Another step to consider are sAMAccountNames conatining a invalid set of characters and so on. I’m going to go through each step of the scripts and explain in detail how to avoid the exceptions that we might encounter in each new post regarding the migration.

The Scripts will also use the Get-AD.ps1 script when chekcing if objects exist in the Domain.

Next step is Part 1.1: Adding Ou Structure using Powershell

The Get-AD.ps1 script.

Here’s a link to the Csv File refered to in this post.

Rating 3.00 out of 5
[?]

Migrate From Windows Server 2003 to Windows Server 2008 R2 and Windows 7 Using PowerShell

April 11th, 2009 Niklas Goude No comments

Windows 7 and Windows Server 2008 R2 are just around the Corner. Beta Versions are very promising and, as it seems, the best OS that Microsoft has ever done! This is something that’s not easy to accomplish in the Beta stage of an OS, but Microsoft has pulled it off! The comparisons that I’ve made with previous Operating Systems are entirely based on self observations.

I’m hoping that alot of people share my enthusiasm regarding the Windows 7 technologies and I would like to share my Beta tests with the Microsoft Community. I’m aware that a few commands and techniques may vary from the final Release so the following posts might not be accurate when the final build of Windows 7 / 2008 R2 are released. I will try to keep these posts up to date and follow Microsfts development of Windows 7 and Windows Server 2008 R2.

Scenraio

You have a Windows 2003 Active-Directory Environment that you want to Updgrade / migrate to a Windows 2008 R2 environment. Microsoft have a great tool called ADMT (Active Directory Migration Tool) which allows you to perform the appropriate steps when migration from Windows 2003 to Windows 2008. But since this is a PowerShell Blog, I’m going to show examples on doing all these steps through PowerShell. I’m planning on showing the following steps:

Windows 2003

Windows 2008 R2

  • Gathering information from a 2003 Active Directory Domain through PowerShell
  • Migarting OU Structure to a Active-Directory 2008 R2 Server Through PowerShell
  • Migarting Users to a Active-Directory 2008 R2 Server Through PowerShell
  • Migarting Computers to a Active-Directory 2008 R2 Server Through PowerShell
  • Migarting Groups to a Active-Directory 2008 R2 Server Through PowerShell
  • Migarting Group Membership to a Active-Directory 2008 R2 Server Through PowerShell
  • Migrating HomeFolders to a Active-Directory 2008 R2 Server Through PowerShell
  • Migrating a Windows 7 Client to a Active-Directory 2008 R2 Server Through PowerShell
  • Note that all steps are built from a test environment and may require slight adjustments to fit your environmnent.

    Rating 3.00 out of 5
    [?]

Get-AD.ps1

February 27th, 2009 Niklas Goude No comments

Get-AD.ps1

This Script gets Information About Objects in Active-Directory. It’s got a few Parameters and Switches that allows us to specify what to search for and how to Return the objects found. You can choose which information to return through the Property parameter, you can Save the Information to a Csv file, You can return a System.DirectoryServices.DirectoryEntry Object that you can work with through PowerShell.. you can do lots of things.

Parameters:

  • -Domain Name of the Domain (Required)
  • -OU Name of Organizational Unit (Optional)
  • -User Name of the User (Optional)
  • -Group Name of the Group (Optional)
  • -Computer Name of the Computer (Optional)
  • -Filter Filter on Specified Criteria, default is name (optional)
  • -CustomFilter Create A custom SearchFilter (optional)
  • -CustomAll Create A Custom SerachFilter, searches for All Objects (optional)
  • -Property Specify one or more Properties to Return (Optional)
  • -ToCsv Saves the Output to a Csv File (Optional)
  • -ToObject Returns a System.DirectoryServices.DirectoryEntry Object (optional)
  • -IncreasePageSize Exceeds the default limit of 1000 Objects (optional)
  • -help Prints the HelpFile (Optional)

Here are a few Example Scenarios on running The Script

You want to display a HelpText about the Script


PS > Get-AD.ps1 -Help

You want to Display Domain Information About Your Domain


PS > Get-AD.ps1 -Domain apa.corp

You want to Connect to a Domain and store the Object in a Variable


PS > $Domain = Get-AD.ps1 -Domain apa.corp -ToObject

You want to retrieve All OrganizationalUnits in your Domain and store their distiguishedName in a Csv file


PS > Get-AD.ps1 -Domain apa.corp -OU AllOU -Property distinguishedName -ToCsv C:MyFolderMyOUFile.csv

You want to Get all Users and display their name and mail in your PowerShell Session


PS > Get-AD.ps1 -Domain apa.corp -User AllUsers -Property cn, mail

You want to Find a User, but you only know the Users sAMAccountName


PS > Get-AD.ps1 -Domain apa.corp -User User1 -Filter sAMAccountName -Property cn, mail

You want to Create a Csv File with all Computers in your domain


PS > Get-AD.ps1 -Domain apa.corp -Computer AllCOmputers -Property Name -ToCsv C:\MyFolderMyOUFile.csv

You can Download the Script here

Rating 3.00 out of 5
[?]

Searching through Active-Directory on Windows 2008 Server Core R2

January 17th, 2009 Niklas Goude 1 comment

Searching through Active-Directory can be done using the DirectorySearcher. First we need to connect to Active-Directory.


PS > $Connection = "LDAP://Server1/DC=APA,DC=CORP"
PS > $AD = [adsi] $Connection

We then create a new object containing the Searcher.


PS > $Searcher = New-Object System.DirectoryServices.DirectorySearcher $AD

In order to search through Active-Directory we have to specify a filter that tells the searcher what kind of information we wnat to look up.
First we define which objectClass we want to search through and then we specify the criterias. First we’ll search for a specicif Group.


PS > $Searcher.Filter = '(&(objectClass=Group)(name=NewGroup))'
PS > $Group = ($Searcher.FindOne()).GetDirectoryEntry()
PS > $Group


distinguishedName : {CN=NewGroup,OU=NewOU,DC=APA,DC=CORP}
Path              : LDAP://Server1/CN=NewGroup,OU=NewOU,DC=APA,DC=CORP

If we instead want to search for All groups we can specify this in the searcher.


PS > $Searcher.Filter = '(objectClass=Group)'
PS > $AllGroups = $Searcher.FindAll()
PS > $AllGroups

Path                                    Properties
----                                    ----------
LDAP://Server1/CN=Administrators,CN=... {admincount, iscriticalsystemobject,...
LDAP://Server1/CN=Users,CN=Builtin,D... {iscriticalsystemobject, samaccountn...
LDAP://Server1/CN=Guests,CN=Builtin,... {iscriticalsystemobject, samaccountn...
LDAP://Server1/CN=Print Operators,CN... {admincount, iscriticalsystemobject,...

We can also present the returned information in a variaty of ways, using ForEach-Object CmdLet.


PS > $AllGroups | ForEach { $_.GetDirectoryEntry() }


distinguishedName : {CN=Administrators,CN=Builtin,DC=APA,DC=CORP}
Path              : LDAP://Server1/CN=Administrators,CN=Builtin,DC=APA,DC=CORP

distinguishedName : {CN=Users,CN=Builtin,DC=APA,DC=CORP}
Path              : LDAP://Server1/CN=Users,CN=Builtin,DC=APA,DC=CORP

distinguishedName : {CN=Guests,CN=Builtin,DC=APA,DC=CORP}
Path              : LDAP://Server1/CN=Guests,CN=Builtin,DC=APA,DC=CORP

distinguishedName : {CN=Print Operators,CN=Builtin,DC=APA,DC=CORP}
Path              : LDAP://Server1/CN=Print Operators,CN=Builtin,DC=APA,DC=CORP

If we instead want to search for a User-Object, we can specify this in the Filter.


PS > $Searcher.Filter = '(&(objectClass=User)(name=jeapic))'
PS > $User = ($Searcher.FindOne()).GetDirectoryEntry()
PS > $User


distinguishedName : {CN=jeapic,OU=NewOU,DC=APA,DC=CORP}
Path              : LDAP://Server1/CN=jeapic,OU=NewOU,DC=APA,DC=CORP

Seraching for all Users is done as shown below


PS > $Searcher.Filter = '(objectClass=User)'
PS > $AllUser = $Searcher.FindAll()
PS > $AllUser

Path                                    Properties
----                                    ----------
LDAP://Server1/CN=Administrator,CN=U... {admincount, logonhours, iscriticals...
LDAP://Server1/CN=Guest,CN=Users,DC=... {iscriticalsystemobject, samaccountn...
LDAP://Server1/CN=SERVER1,OU=Domain ... {primarygroupid, iscriticalsystemobj...
LDAP://Server1/CN=krbtgt,CN=Users,DC... {admincount, countrycode, samaccount...
LDAP://Server1/CN=Client1,CN=Compute... {primarygroupid, iscriticalsystemobj...
LDAP://Server1/CN=SERVER2,CN=Compute... {primarygroupid, iscriticalsystemobj...
LDAP://Server1/CN=jeapic,OU=NewOU,DC... {primarygroupid, mail, displayname, ...

And last, searching for computers in Active-Directory, first we’ll search for one Computer


PS > $Searcher.Filter = '(&(objectClass=Computer)(name=Client1))'
PS > $Computer = ($Searcher.FindOne()).GetDirectoryEntry()
PS > $Computer


distinguishedName : {CN=Client1,CN=Computers,DC=APA,DC=CORP}
Path              : LDAP://Server1/CN=Client1,CN=Computers,DC=APA,DC=CORP

And finally, searching for All Computers.


PS > $Searcher.Filter = '(objectClass=Computer)'
PS > $AllComputer = $Searcher.FindAll()
PS >
PS > $AllComputer

Path                                    Properties
----                                    ----------
LDAP://Server1/CN=SERVER1,OU=Domain ... {primarygroupid, iscriticalsystemobj...
LDAP://Server1/CN=Client1,CN=Compute... {primarygroupid, iscriticalsystemobj...
LDAP://Server1/CN=SERVER2,CN=Compute... {primarygroupid, iscriticalsystemobj...

Below is the code used in this Post


$Connection = "LDAP://Server1/DC=APA,DC=CORP"
$AD = [adsi] $Connection

$Searcher = New-Object System.DirectoryServices.DirectorySearcher $AD
$Searcher.Filter = '(&(objectClass=Group)(name=NewGroup))'

$Group = ($Searcher.FindOne()).GetDirectoryEntry()
$Group

$Searcher.Filter = '(objectClass=Group)'

$AllGroups = $Searcher.FindAll()
$AllGroups | ForEach { $_.GetDirectoryEntry() }

$Searcher.Filter = '(&(objectClass=User)(name=jeapic))'

$User = ($Searcher.FindOne()).GetDirectoryEntry()
$User

$Searcher.Filter = '(objectClass=User)'

$AllUser = $Searcher.FindAll()

$Searcher.Filter = '(&(objectClass=Computer)(name=Client1))'

$Computer = ($Searcher.FindOne()).GetDirectoryEntry()
$Computer

$Searcher.Filter = '(objectClass=Computer)'

$AllComputer = $Searcher.FindAll()
$AllComputer

Rating 3.00 out of 5
[?]

Adding User To Group in Active-Directory on Windows 2008 Server Core R2

January 17th, 2009 Niklas Goude No comments

To add our new User to our Group, the add() method is used as shown below.


PS > $Connection = "LDAP://Server1/CN=NewGroup,OU=NewOU,DC=APA,DC=CORP"
PS > $Group = [adsi] $Connection
PS > $User = "LDAP://Server1/CN=jeapic,OU=NewOU,DC=APA,DC=CORP"
PS > $Group.Add($User)

If we look at the memebers of the group, our user will be added.


PS > $Group.member

CN=jeapic,OU=NewOU,DC=APA,DC=CORP

In the AD MMC Snapin, we can view the changes that we made.

servercore-08

And if we want to remove a user from a Group we can use the Delete() method.


PS > $Group.Remove($User)

Below is the code used in this post


$Connection = "LDAP://Server1/CN=NewGroup,OU=NewOU,DC=APA,DC=CORP"
$Group = [adsi] $Connection

$User = "LDAP://Server1/CN=jeapic,OU=NewOU,DC=APA,DC=CORP"

$Group.Add($User)

Rating 3.00 out of 5
[?]

Creating a User in Active-Directory on Windows 2008 Server Core R2

January 17th, 2009 Niklas Goude No comments

Creating a user is basically the same as creating a Group or an OU. First we cast the OU we want to use into a [adsi] object and then start setting the properties. After adding all properties we set a password and set Disabled to false, otherwise the account will be disabled.


PS > $Connection = "LDAP://Server1/OU=NewOU,DC=APA,DC=CORP"
PS > $OU = [adsi] $Connection
PS > $User = $OU.Create("user", "cn=jeapic")
PS > $User.Put("sAMAccountName", "jeapic")
PS > $User.Put("userPrincipalName", "jeapic@apa.corp")
PS > $User.Put("DisplayName", "Jean-Luc Picard")
PS > $User.Put("givenName", "Jean-Luc")
PS > $User.Put("sn", "Picard")
PS > $User.Put("Description", "Captain of the Enterprise")
PS > $User.Put("mail", "picard@enterprise.com")
PS > $User.SetInfo()
PS >
PS > $User.PsBase.Invoke("SetPassword", "Password123")
PS > $User.PsBase.InvokeSet("AccountDisabled", $false)
PS > $User.SetInfo()

If we want to set the account to never expires, we can edit the UserAccountControl


PS > $User.userAccountControl[0] = $User.userAccountControl[0] -bor (65536)
PS > $User.SetInfo()

Now we can check out the properties on our User.


PS > $User | Format-List *


objectClass           : {top, person, organizationalPerson, user}
cn                    : {jeapic}
sn                    : {Picard}
description           : {Captain of the Enterprise}
givenName             : {Jean-Luc}
distinguishedName     : {CN=jeapic,OU=NewOU,DC=APA,DC=CORP}
instanceType          : {4}
whenCreated           : {1/18/2009 12:08:29 AM}
whenChanged           : {1/18/2009 12:08:32 AM}
displayName           : {Jean-Luc Picard}
uSNCreated            : {System.__ComObject}
uSNChanged            : {System.__ComObject}
name                  : {jeapic}
objectGUID            : {77 84 253 130 36 215 146 76 155 38 10 217 57 208 44 45
                        }
userAccountControl    : {66080}
badPwdCount           : {0}
codePage              : {0}
countryCode           : {0}
badPasswordTime       : {System.__ComObject}
lastLogoff            : {System.__ComObject}
lastLogon             : {System.__ComObject}
pwdLastSet            : {System.__ComObject}
primaryGroupID        : {513}
objectSid             : {1 5 0 0 0 0 0 5 21 0 0 0 171 166 141 168 63 138 126 92
                         158 59 183 83 83 4 0 0}
accountExpires        : {System.__ComObject}
logonCount            : {0}
sAMAccountName        : {jeapic}
sAMAccountType        : {805306368}
userPrincipalName     : {jeapic@apa.corp}
objectCategory        : {CN=Person,CN=Schema,CN=Configuration,DC=APA,DC=CORP}
dSCorePropagationData : {1/1/1601 12:00:00 AM}
mail                  : {picard@enterprise.com}
nTSecurityDescriptor  : {System.__ComObject}
AuthenticationType    : Secure
Children              : {}
Guid                  : 4d54fd8224d7924c9b260ad939d02c2d
ObjectSecurity        : System.DirectoryServices.ActiveDirectorySecurity
NativeGuid            : 4d54fd8224d7924c9b260ad939d02c2d
NativeObject          : System.__ComObject
Parent                : LDAP://Server1/OU=NewOU,DC=APA,DC=CORP
Password              :
Path                  : LDAP://Server1/cn=jeapic,OU=NewOU,DC=APA,DC=CORP
Properties            : {objectClass, cn, sn, description...}
SchemaClassName       : user
SchemaEntry           : System.DirectoryServices.DirectoryEntry
UsePropertyCache      : True
Username              :
Options               : {}
Site                  :
Container             :

If we check out the User through the Active-Directory MMC Snapin we can varify that all information added through PowerShell is added.

servercore-07

If we want to Delete a User in Active-Directory, we can use the Delete() method.


PS > $Connection = "LDAP://Server1/OU=NewOU,DC=APA,DC=CORP"
PS > $OU = [adsi] $Connection
PS > $OU.delete(”user”,”CN=UserToDelete”)

Below is the code used in this post


$Connection = "LDAP://Server1/OU=NewOU,DC=APA,DC=CORP"
$OU = [adsi] $Connection
$User = $OU.Create("user", "cn=jeapic")
$User.Put("sAMAccountName", "jeapic")
$User.Put("userPrincipalName", "jeapic@apa.corp")
$User.Put("DisplayName", "Jean-Luc Picard")
$User.Put("givenName", "Jean-Luc")
$User.Put("sn", "Picard")
$User.Put("Description", "Captain of the Enterprise")
$User.Put("mail", "picard@enterprise.com")
$User.SetInfo()

$User.PsBase.Invoke("SetPassword", "Password123")
$User.PsBase.InvokeSet("AccountDisabled", $false)
$User.SetInfo()

$User.userAccountControl[0] = $User.userAccountControl[0] -bor (65536)
$User.SetInfo()

$Connection = "LDAP://Server1/OU=NewOU,DC=APA,DC=CORP"
$OU = [adsi] $Connection
$OU.delete("user", "cn=UserToDelete")

Rating 3.00 out of 5
[?]

Creating a Group in Active-Directory on Windows 2008 Server Core R2

January 17th, 2009 Niklas Goude No comments

We can create Groups in Active-Directory through PowerShell. Step one is to make a connection to the OU where you want to place your Group. In this example I’ll use the OU that i created in a previous post.


PS > $Connection = "LDAP://OU=NewOU,DC=BPA,DC=CORP"
PS > $OU = [adsi] $Connection
PS > $OU


distinguishedName : {OU=NewOU,DC=APA,DC=CORP}
Path              : LDAP://OU=NewOU,DC=APA,DC=CORP

Next, we use the Create() method to create a New Group.


PS > $Group = $OU.Create("Group", "CN=NewGroup")
PS > $Group.setinfo()

If we look at the group through the MMC snapin.

servercore-05

It’s also possible to retrieve detailed information if we pipe the object to the Format-List CmdLet.


PS > $Group | Format-List *


objectClass           : {top, group}
cn                    : {NewGroup}
distinguishedName     : {CN=NewGroup,OU=NewOU,DC=APA,DC=CORP}
instanceType          : {4}
whenCreated           : {1/17/2009 7:45:09 AM}
whenChanged           : {1/17/2009 7:45:09 AM}
uSNCreated            : {System.__ComObject}
uSNChanged            : {System.__ComObject}
name                  : {NewGroup}
objectGUID            : {54 186 37 137 40 211 36 68 191 63 127 148 134 182 116
                        2}
objectSid             : {1 5 0 0 0 0 0 5 21 0 0 0 171 166 141 168 63 138 126 92
                         158 59 183 83 80 4 0 0}
sAMAccountName        : {$G21000-VS2BCS6RM3JL}
sAMAccountType        : {268435456}
groupType             : {-2147483646}
objectCategory        : {CN=Group,CN=Schema,CN=Configuration,DC=APA,DC=CORP}
dSCorePropagationData : {1/1/1601 12:00:00 AM}
nTSecurityDescriptor  : {System.__ComObject}
AuthenticationType    : Secure
Children              : {}
Guid                  : 36ba258928d32444bf3f7f9486b67402
ObjectSecurity        : System.DirectoryServices.ActiveDirectorySecurity
NativeGuid            : 36ba258928d32444bf3f7f9486b67402
NativeObject          : System.__ComObject
Parent                : LDAP://Server1/OU=NewOU,DC=APA,DC=CORP
Password              :
Path                  : LDAP://Server1/CN=NewGroup,OU=NewOU,DC=APA,DC=CORP
Properties            : {objectClass, cn, distinguishedName, instanceType...}
SchemaClassName       : Group
SchemaEntry           : System.DirectoryServices.DirectoryEntry
UsePropertyCache      : True
Username              :
Options               : {}
Site                  :
Container             :

If we inspect the returned information above, sAMAccountName looks a little funny, changing that is simple through PowerShell.


PS > $Connection = "LDAP://Server1/CN=NewGroup,OU=NewOU,DC=APA,DC=CORP"
PS > $Group = [adsi] $Connection

PS > $Group.put("sAMAccountName", ”NewGroup")
PS > $Group.SetInfo()

PS > $Group.sAMAccountName

NewGroup

It’s also possible to change the property directly as shown below.


PS > $Group.sAMAccountName = "Another Name"
PS > $Group.SetInfo()

Below is the code used in this post


$Connection = "LDAP://OU=NewOU,DC=APA,DC=CORP"
$OU = [adsi] $Connection

$Group = $OU.Create("Group", "CN=NewGroup")
$Group.setinfo()

$Connection = "LDAP://Server1/CN=NewGroup,OU=NewOU,DC=APA,DC=CORP"

$Group = [adsi] $Connection
$Group.put("sAMAccountName", ”NewGroup")
$Group.SetInfo()

$Group.sAMAccountName = "Another Name"
$Group.SetInfo()

Rating 3.00 out of 5
[?]

Creating an OU in Active-Directory on Windows 2008 Server Core R2

January 17th, 2009 Niklas Goude 1 comment

When creating Organizational-Units through PowerShell, we can use the Create() method. First we need to connect to the place where we want to create it. In this example I’m going to create an OU in the top level of my domain. If you want to create further down in the structure, simply connect to the level that you wish to create the OU in.


PS > $Connect = "LDAP://Server1/DC=APA,DC=CORP"
PS > $AD = [adsi] $Connect

PS > $OU = $AD.Create("OrganizationalUnit", "OU=NewOU")
PS > $OU.SetInfo()

If we call on our variable $OU, it returns information about the object that we just created.


PS > $OU = [adsi] "LDAP://Server1/OU=NewOU,DC=APA,DC=CORP"
PS > $OU


distinguishedName : {OU=NewOU,DC=APA,DC=CORP}
Path              : LDAP://Server1/OU=NewOU,DC=APA,DC=CORP

And if we look in the Active-Directory snapin, we can see that our new OU is created.

servercore-03

If we want to explore the properties on our Organizational-Unit, we can simply pipe the object to the Format-List CmdLet


PS > $OU | Format-List *


objectClass           : {top, organizationalUnit}
ou                    : {NewOU}
distinguishedName     : {OU=NewOU,DC=APA,DC=CORP}
instanceType          : {4}
whenCreated           : {1/17/2009 7:34:43 AM}
whenChanged           : {1/17/2009 7:34:43 AM}
uSNCreated            : {System.__ComObject}
uSNChanged            : {System.__ComObject}
name                  : {NewOU}
objectGUID            : {169 138 178 239 63 60 113 76 153 251 193 11 61 99 27 1
                        75}
objectCategory        : {CN=Organizational-Unit,CN=Schema,CN=Configuration,DC=A
                        PA,DC=CORP}
dSCorePropagationData : {1/1/1601 12:00:00 AM}
nTSecurityDescriptor  : {System.__ComObject}
AuthenticationType    : Secure
Children              : {}
Guid                  : a98ab2ef3f3c714c99fbc10b3d631baf
ObjectSecurity        : System.DirectoryServices.ActiveDirectorySecurity
NativeGuid            : a98ab2ef3f3c714c99fbc10b3d631baf
NativeObject          : System.__ComObject
Parent                : LDAP://Server1/DC=APA,DC=CORP
Password              :
Path                  : LDAP://Server1/OU=NewOU,DC=APA,DC=CORP
Properties            : {objectClass, ou, distinguishedName, instanceType...}
SchemaClassName       : organizationalUnit
SchemaEntry           : System.DirectoryServices.DirectoryEntry
UsePropertyCache      : True
Username              :
Options               : {}
Site                  :
Container             :

If we want to modify properties, we can use the put() method. In this example we will set the City and the Description of the OU.


PS > $OU.put("l", "Gothenburg")
PS > $OU.put("Description", "www.PowerShell.nu")
PS > $OU.SetInfo()

We can check the values set by calling the Objects Property.


PS > $OU.l

Gothenburg

PS > $OU.Description

www.PowerShell.nu

If we look at the properties on our OU in the Active-Directory snapin we can see the changes.

servercore-04

And last step, removing an Organizational-Unit. It’s possible to accomplish through the deleteTree() method as shown below.


PS > $OU.psbase.deleteTree()

Below is the complete code used in this example:


$Connect = "LDAP://Server1/DC=APA,DC=CORP"
$AD = [adsi] $Connect

$OU = $AD.Create("OrganizationalUnit", "ou=NewOU")
$OU.SetInfo()

$OU.put("l", "Gothenburg")
$OU.put("Description", "www.PowerShell.nu")
$OU.setinfo()

$OU.psbase.deleteTree()

Rating 3.00 out of 5
[?]

Connecting to Active-Directory on Windows 2008 Server Core R2

January 17th, 2009 Niklas Goude 1 comment

PowerShell doesn’t have any built in CmdLet for working with Active-Directory. Quest has put togheter a couple of real nice Active-Directory CmdLets that automate Active-Directory tasks. Anyway, I’m going to do a couple of posts on managing Active-Directory on a Server Core, through the DirectoryEntryAdapter. First off, let’s take a quick look at my dev Active-Directory.

servercore-02

Nothing strange here, Domain name is APA.CORP and the server is called Server1

Lets connect to the Active-Directory through PowerShell. First we create a connection string.


PS > $Connection = "LDAP://DC=APA,DC=CORP"

Next, we connect to Active-Directory through [adsi]


PS > $AD = [adsi] $Connection
PS > $AD


distinguishedName : {DC=APA,DC=CORP}
Path              : LDAP://Server1/DC=APA,DC=CORP

If you have alot of domain controllers in your farm you can specify which DC you want to connect to and also specify the LDAP port 389 in the connectionstring:


PS > $Connect = LDAP://Server1:389/DC=APA,DC=CORP
PS > $AD = [adsi] $Connection

If we want to explore our AD through PowerShell, we can use PsBase.Children to retrieve its children.


PS > $AD.PsBase.Children


distinguishedName : {CN=Builtin,DC=APA,DC=CORP}
Path              : LDAP://Server1/CN=Builtin,DC=APA,DC=CORP

distinguishedName : {CN=Computers,DC=APA,DC=CORP}
Path              : LDAP://Server1/CN=Computers,DC=APA,DC=CORP

distinguishedName : {OU=Domain Controllers,DC=APA,DC=CORP}
Path              : LDAP://Server1/OU=Domain Controllers,DC=APA,DC=CORP

distinguishedName : {CN=ForeignSecurityPrincipals,DC=APA,DC=CORP}
Path              : LDAP://Server1/CN=ForeignSecurityPrincipals,DC=APA,DC=CORP

distinguishedName : {CN=Infrastructure,DC=APA,DC=CORP}
Path              : LDAP://Server1/CN=Infrastructure,DC=APA,DC=CORP

distinguishedName : {CN=LostAndFound,DC=APA,DC=CORP}
Path              : LDAP://Server1/CN=LostAndFound,DC=APA,DC=CORP

distinguishedName : {CN=Managed Service Accounts,DC=APA,DC=CORP}
Path              : LDAP://Server1/CN=Managed Service Accounts,DC=APA,DC=CORP

distinguishedName : {CN=NTDS Quotas,DC=APA,DC=CORP}
Path              : LDAP://Server1/CN=NTDS Quotas,DC=APA,DC=CORP

distinguishedName : {CN=Program Data,DC=APA,DC=CORP}
Path              : LDAP://Server1/CN=Program Data,DC=APA,DC=CORP

distinguishedName : {CN=System,DC=APA,DC=CORP}
Path              : LDAP://Server1/CN=System,DC=APA,DC=CORP

distinguishedName : {CN=Users,DC=APA,DC=CORP}
Path              : LDAP://Server1/CN=Users,DC=APA,DC=CORP

It’s also possible to list all properties through the Format-List CmdLet.


PS > $AD | Format-List *


objectClass                      : {top, domain, domainDNS}
distinguishedName                : {DC=APA,DC=CORP}
instanceType                     : {5}
whenCreated                      : {1/17/2009 6:29:21 AM}
whenChanged                      : {1/17/2009 6:33:07 AM}
subRefs                          : {DC=ForestDnsZones,DC=APA,DC=CORP, DC=Domain
                                   DnsZones,DC=APA,DC=CORP, CN=Configuration,DC
                                   =APA,DC=CORP}
uSNCreated                       : {System.__ComObject}
uSNChanged                       : {System.__ComObject}
name                             : {APA}
objectGUID                       : {164 249 62 250 183 125 32 74 162 127 129 25
                                   5 219 196 229 116}
creationTime                     : {System.__ComObject}
forceLogoff                      : {System.__ComObject}
lockoutDuration                  : {System.__ComObject}
lockOutObservationWindow         : {System.__ComObject}
lockoutThreshold                 : {0}
maxPwdAge                        : {System.__ComObject}
minPwdAge                        : {System.__ComObject}
minPwdLength                     : {7}
modifiedCountAtLastProm          : {System.__ComObject}
nextRid                          : {1000}
pwdProperties                    : {1}
pwdHistoryLength                 : {24}
objectSid                        : {1 4 0 0 0 0 0 5 21 0 0 0 171 166 141 168 63
                                    138 126 92 158 59 183 83}
serverState                      : {1}
uASCompat                        : {1}
modifiedCount                    : {System.__ComObject}
auditingPolicy                   : {0 1}
nTMixedDomain                    : {0}
rIDManagerReference              : {CN=RID Manager$,CN=System,DC=APA,DC=CORP}
fSMORoleOwner                    : {CN=NTDS Settings,CN=SERVER1,CN=Servers,CN=D
                                   efault-First-Site-Name,CN=Sites,CN=Configura
                                   tion,DC=APA,DC=CORP}
systemFlags                      : {-1946157056}
wellKnownObjects                 : {System.__ComObject, System.__ComObject, Sys
                                   tem.__ComObject, System.__ComObject...}
objectCategory                   : {CN=Domain-DNS,CN=Schema,CN=Configuration,DC
                                   =APA,DC=CORP}
isCriticalSystemObject           : {True}
gPLink                           : {[LDAP://CN={31B2F340-016D-11D2-945F-00C04FB
                                   984F9},CN=Policies,CN=System,DC=APA,DC=CORP;
                                   0]}
dSCorePropagationData            : {1/17/2009 6:30:55 AM, 1/1/1601 12:00:04 AM}
otherWellKnownObjects            : {System.__ComObject}
masteredBy                       : {CN=NTDS Settings,CN=SERVER1,CN=Servers,CN=D
                                   efault-First-Site-Name,CN=Sites,CN=Configura
                                   tion,DC=APA,DC=CORP}
ms-DS-MachineAccountQuota        : {10}
msDS-Behavior-Version            : {2}
msDS-PerUserTrustQuota           : {1}
msDS-AllUsersTrustQuota          : {1000}
msDS-PerUserTrustTombstonesQuota : {10}
msDs-masteredBy                  : {CN=NTDS Settings,CN=SERVER1,CN=Servers,CN=D
                                   efault-First-Site-Name,CN=Sites,CN=Configura
                                   tion,DC=APA,DC=CORP}
msDS-IsDomainFor                 : {CN=NTDS Settings,CN=SERVER1,CN=Servers,CN=D
                                   efault-First-Site-Name,CN=Sites,CN=Configura
                                   tion,DC=APA,DC=CORP}
msDS-NcType                      : {0}
dc                               : {APA}
nTSecurityDescriptor             : {System.__ComObject}
AuthenticationType               : Secure
Children                         : {Builtin, Computers, Domain Controllers, For
                                   eignSecurityPrincipals...}
Guid                             : a4f93efab77d204aa27f81ffdbc4e574
ObjectSecurity                   : System.DirectoryServices.ActiveDirectorySecu
                                   rity
NativeGuid                       : a4f93efab77d204aa27f81ffdbc4e574
NativeObject                     : System.__ComObject
Parent                           : LDAP://Server1/DC=CORP
Password                         :
Path                             : LDAP://Server1/DC=APA,DC=CORP
Properties                       : {objectClass, distinguishedName, instanceTyp
                                   e, whenCreated...}
SchemaClassName                  : domainDNS
SchemaEntry                      : System.DirectoryServices.DirectoryEntry
UsePropertyCache                 : True
Username                         :
Options                          : {}
Site                             :
Container                        :

Below is the complete code used in this example


$Connection = "LDAP://DC=BPA,DC=CORP"

$AD = [adsi] $Connection
$AD

$AD.PsBase.Children

$AD | Format-List *

Rating 3.00 out of 5
[?]

Installing Active-Directory on Windows 2008 Server Core R2

January 17th, 2009 Niklas Goude No comments

Server Core is a scaled back installation of Windows Server 2008 where no Windows Explorer is installed. The configuration is done entirly through the Command-Line interface, or by connecting remote using MMC.

All examples regarding Server Core will be done using the Windows Server 2008 R2 Beta edition, available at MSDN.

Starting off, since this is a PowerShell blog, we’ll start with installing PowerShell.


C:>start /w ocsetup MicrosoftWindowsPowerShell

After PowerShell is installed, browse to the PowerShell installation folder and start powershell.exe.


C:>%WINDIR%System32WindowsPowerShellv1.0powershell.exe

Next, we want to configure the Network Adapter Settings. this can be done either from the netsh or through WMI. In this example I’ll describe how to do it through WMI.

First we create a variable that contains information regarding our Network Adapter Configuration. To ensure that we connect to the correct Adapter, we use the Where-Object CmdLet to specify which Adapter we want to use. If you have two enabled Network Adapters it might be a good idea to have two criterias.


PS > $NetworkConfig = Get-WmiObject Win32_NetworkAdapterConfiguration
PS > $NetworkConfig | Where {$_.IPEnabled -eq $true -and $_.Description -match "Intel"}

Now that we have pinpointed our Network Adapter, we can prepare the settings that we want.


PS > $IP = "10.0.0.2"
PS > $SubNet = "255.0.0.0"
PS > $Gateway = "10.0.0.1"
PS > $Metric = [int32]1

And finally, we can update the Network Adapter Configuration with our custom settings.


PS > $NetworkConfig.EnableStatic($IP,$SubNet)
PS > $NetworkConfig.SetGateWays($Gateway,$Metric)

Changing the computername might also be a good idea. The computername can be changed through the netdom command or through wmi as the example below shows.


PS > $Computer = Get-WmiObject Win32_ComputerSystem
PS > $Computer.Rename("Server1","Password1,"Administrator")

The Server requires a Reboot before the computername changes.


PS > shutdown /r /t 0

The Active-Directory Role is added through the dcpromo command. The command takes arguments that specify the type of AD you want to setup. It’s also possible to create a list contining the information and run dcpromo with the unattend switch.

Here is an example of the list I used in my test domain. A complete description of available switches are available on TechNet

[DCINSTALL]
ReplicaOrNewDomain=Domain
NewDomain=Forest
NewDomainDNSName=APA.CORP
DomainNetBiosName=APA
InstallDNS=yes
RebootOnCompletion=Yes
SafeModeAdminPassword=Password1

Save the list in a txt file, then run dcpromo with the unattend switch and specify the path to the txt file.


PS > dcpromo /unattend:C:DCINSTALL.txt

Restart the Client and when the login screen appears, you will be able to Log on to your New Domain.

servercore-01

Below is the code used in this post:


start /w ocsetup MicrosoftWindowsPowerShell

%WINDIR%System32WindowsPowerShellv1.0powershell.exe

$NetworkConfig = Get-WmiObject Win32_NetworkAdapterConfiguration
$NetworkConfig | Where {$_.IPEnabled -eq $true -and $_.Description -match "Intel"}

$IP = "10.0.0.2"
$SubNet = "255.0.0.0"
$Gateway = "10.0.0.1"
$Metric = [int32]1

$NetworkConfig.EnableStatic($IP,$SubNet)
$NetworkConfig.SetGateWays($Gateway,$Metric)

$Computer = Get-WmiObject Win32_ComputerSystem
$Computer.Rename("Server1","Password1,"Administrator")

shutdown /r /t 0

dcpromo /unattend:C:DCINSTALL.txt

Rating 3.00 out of 5
[?]

Adding Users to Sharepoint

January 6th, 2009 Niklas Goude 1 comment

Adding Users from Active-Directory into Sharepoint is done in 2 steps. First we will need to Get the information required from Active-Directory and then we need to Add the informtaion into Sharepoint.

Lets start with Active-Directory. Below is an image of the Active-Directory Design in this example:

active-directory-01

Since we want to Get the User information we need to connect to the correct OU through ADSI. The Connection string to the User OU that we want to access would look like this

LDAP://OU=Site1 Users,OU=Site1,OU=Sites,DC=BPA,DC=CORP

Here’s how to connect to the OU through PowerShell:

PS > $ConnectionString = "LDAP://OU=Site1 Users,OU=Site1,OU=Sites,DC=BPA,DC=CORP"
PS > $AD = [adsi]$ConnectionString
PS > $AD
distinguishedName
-----------------
{OU=Site1 Users,OU=Site1,OU=Sites,DC=bpa,DC=corp}

This shows that we have connected to the correct OU. To retrieve information about the Users in the OU we have to access the children within the object.

PS > $AD.PsBase.Children
distinguishedName
-----------------
{CN=user1,OU=Site1 Users,OU=Site1,OU=Sites,DC=bpa,DC=corp}
{CN=user2,OU=Site1 Users,OU=Site1,OU=Sites,DC=bpa,DC=corp}
{CN=user3,OU=Site1 Users,OU=Site1,OU=Sites,DC=bpa,DC=corp}
{CN=User4,OU=Site1 Users,OU=Site1,OU=Sites,DC=bpa,DC=corp}

Now that we have all the Users in the OU we can start collecting the information. But first let’s check what we need. The User items in WSS 3.0 have a couple of settable values and not all values are available Properties in Active-Directory.

sharepoint-05

Sharepoint actually looks up Department and Job Title if they exist in Active-Directory so we dont have to bother about that. What we do need is the Users loginname, mail and name.
To retrieve the information, we will create a filter that takes the information from Active-Directory.

PS > filter UserProperties {
     $_ | select @{ name='sAMAccountName'; Expression={$_.sAMAccountName} },
     @{ name='mail'; Expression={$_.mail} },
     @{ name='displayName'; Expression={$_.displayName} }
 }

Next we will run through all Child objects in the OU and filter them into a new Custom Object.

PS > $User = $AD.PsBase.Children | UserProperties
PS > $User
sAMAccountName                          mail                                    displayName
--------------                          ----                                    -----------
user1                                   user1@mail.com                          user1
user2                                   user2@mail.com                          user2
user3                                   user3@mail.com                          user3
user4                                   user4@mail.com                          User4

Now that we have the User information stored in a PowerShell object, we can use it to create the users in Sharepoint. When adding users to Sharepoint, we have to consider which Role ther Users should have. there are a few available roles to choose from. We can get a list of all roles through the Roles Property.


ps > [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")

PS > $SPSite = New-Object Microsoft.SharePoint.SPSite("http://wss"); $OpenWeb = $SpSite.OpenWeb(); $OpenWeb.Roles | Select Name, Description; $OpenWeb.Dispose(); $SPSite.Dispose()


Name                                                        Description
----                                                        -----------
Full Control                                                Has full control.
Design                                                      Can view, add, update, delete, approve...
Contribute                                                  Can view, add, update, and delete.
Read                                                        Can view only.
Limited Access                                              Can view specific lists, document libraries...

In this example, we will use the Read Role. To add the users to Sharepoint we use a function.


function Add-SPUser([string]$url, [string]$Role, [string]$Domain, [string]$sAMAccountName, [string]$Mail, [string]$DisplayName) {

  [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")

  $SPSite = New-Object Microsoft.SharePoint.SPSite($url);
  $OpenWeb = $SpSite.OpenWeb(); $OpenWeb.Roles | Select Name, Description; $OpenWeb.Dispose(); $SPSite.Dispose()

  $OpenWeb.Roles[$Role].AddUser(
    $Domain + $sAMAccountName,
    $Mail,
    $DisplayName,
    ""
  )
  $OpenWeb.Dispose()
  $SPSite.Dispose()
}

PS > $User | foreach-object {
  Add-SPUser -url http://wss -Role Read -Domain bpa -sAMAccountName $_.sAMAccountName -Mail $_.Mail -DisplayName $_.DisplayName
}

Now the users are added to Sharepoint. Note that Job Title and Department are added automatically, if the values exist in Active-Directory.

sharepoint-06

Rating 3.00 out of 5
[?]