Thursday, August 4, 2011

Finding Users Who Have “Out Of Office” Enabled In Exchange 2010

It might come in handy if you know how to get a list of users who have out of office message turned on. Exchange 2010 shell gives you that ability now.
You can even change the message, set the audience (internal or external), turn it off etc with the shell.
To get a list of users who have out of office scheduled, run the following command.
Get-Mailbox | Get-MailboxAutoReplyConfiguration | Where-Object { $_.AutoReplyState –eq “scheduled” }
The above command gives you much more than you need, including the actual message, start time, end time etc.
If you are only interested in the list of users, run
Get-Mailbox | Get-MailboxAutoReplyConfiguration | Where-Object { $_.AutoReplyState –eq “scheduled” } | fl identity

Find USers with oof scheduled

If you want to get the settings for a particular user (for example Rajith), run
Get-MailboxAutoReplyConfiguration –identity rajith
You can also change the out of office settings for a particular user with the Set-MailboxAutoReplyConfiguration cmdlet.
For example, to turn off the out of office for the user account “Rajith”, run
Set-MailboxAutoReplyConfiguration –identity “Rajith” –AutoreplyState disabled

Disable autoreply

Similarly, if you want to extend the out of office message for a user (change the end time), run
Set-MailboxAutoReplyConfiguration –identity “Rajith” –EndTime 01/12/2009 17:00:00
You can change the actual out of office message (internal and external) by running
Set-MailboxAutoReplyConfiguration –identity “Rajith” –InternalMessage “I won’t be around today guys” –ExternalMessage “I am out of the office today”
Do note that this cmdlets will only work in Exchange 2010 Shell!

How To Set Out-Of-Office (OOF) Message For Another User Using Exchange Control Pane


Anyone who has been in the Exchange field for a while should have come across this kind of a request atleast once; a staff goes on holidays without setting an out-of-office message and calls the IT department to set one for him/her. With 2010 and the new Exchange Control Panel (ECP), this request can be easily handled.
Login to the ECP as an administrator. Use owaurl/ecp or owaurl/owa and click Options.
ECP Login
Select “Another User” from the drop down window on the top left hand side. Allow pop-ups for this site.
Manage Another User
Select the user for which you want to set OOF. I am selecting Chakka Rajith as an example.
Select ser
Another window opens up. You will see a warning that “Administrator is working on behalf of the user”.
Warning
Click on “Tell people you are on vacation” link on the right hand side or navigate to Organize Email –> Automatic Replies.
Tell People
Type in the OOF message and click Save.
Set OOF
Close the window, return to the administrator ECP section and log off.
The benefit in this method is that the admin account doesn’t have to be given explicit rights on the user’s mailbox. No messing around with ACLs!


References:

Friday, July 29, 2011

Migration of Novell to Microsoft

When to use a third-party migration tool:

To boil down if you need to purchase a migration tool, such as Quest Software's NDS Migrator, answer these questions:
  • Is your eDirectory tree in good shape?
  • Do you wish to maintain all those user accounts?
  • Are the groups relatively well-maintained?
  • Will you need to build an Active Directory forest?
  • Do you have several hundred or thousands of user objects?
  • Do you have dozens or more NetWare volumes?
  • Is maintaining file ownership important?
  • Will your client PCs need to join an Active Directory domain?
  • Is it important that the Novell Client be removed from the PCs?
  • Do you need to transfer Macintosh files?
If you answered "yes" to any of the above questions, do yourself a favor and purchase a migration tool. DISCLAIMER: I have experience with Quest's NDS Migrator. I will make reference to it in this post, but I don't make any claims, guarantees, or endorse this product or any other migration tool. I have made this product work in my migrations every time. Your results may vary.
Directory Migration:
When using a tool to migrate, you can select the matching criteria for objects from eDirectory to Active Directory. I recommend using (Novell) GUID == SID (Microsoft). A common match many people use is CN == sAMAccountName. The account name is easier to track visually, but if you move eDirectory objects frequently, it breaks the CN match as the eDirectory CN contains the OU and Tree information. If you match on the GUID/SID moving of objects doesn't break the match. This can be very important when many thousands of objects must be migrated. If you only have a few hundred objects or have to match to an exisiting Active Directory domain it is not worth the extra effort to match GUID/SID.
Clean it up or migrate as-is?
Try to avoid the misconception that you should clean things up before you migrate. In past projects, IT leadership has expressed a desire to avoid migrating unneeded data. The problem with that paradigm is that when you hire an outside specialist to run your migration, they are the least qualified to make decisions on what to clean up and what should stay.
Instead, negotiate what you can leave behind. Learn how to make reports on empty groups, accounts which have not been used, and long forgotten test accounts. Beyond that, it is best to just do a wholesale migration of all objects. Once the migration is finished, you can use the more widespread toolset to analyze your Microsoft environment to perform on-going clean-up and maintenance.
I've had migrations where they said they didn't want to migrate anything over five years old. This was easy enough to accomplish. However, there was a legal requirement one month after the project was finished and the NetWare servers were retired. The Windows-centric admins needed to rebuild the Novell infrastructure in a lab and restore some old files. Now, I recommend migrating all the files. If you wish to apply file policies, file deduplication or file life-cycle management, it's easier to manage once it is on a more widely supported platform.
File Migrations:
Moving files and retaining the access rights (ACLs), modified/creation dates, file ownership is a critical step in a successful migration. If your volumes are hundreds of gigabytes or in the terrabyte range, I suggest a hybrid solution for migrating files. Use Microsoft's ROBOCOPY for the file transfer engine then do one or more passes with the migration tool to apply the permissions and file ownership. Robocopy is fast, but it can delete data so be careful.
NOTE: I never use the ROBOCOPY switch /COPYALL when transfering from NetWare to NTFS. It sets the ownership to Everyone which is a security risk as anyone can change the ACL on that file or folder. Instead, use /COPY:DAT
Something to consider when migrating volumes is the future path of file services in your environment. If you plan on implementing DFS, it may be wise to slightly alter your volume sources and target shares to gain some flexibility for the future.
Login Scripts/Mapped Drives:
Every Novell environment I have ever supported or retired has heavily leveraged login scripts and mapped network drives. I typically recommend that environments not rely on login scripts. However, when migrating from Novell, I recommend you develop a login script solution in Active Directory. This sub-topic can be an entire post. If you post comments requesting further input on this, I'd be happy to create a post devoted to this topic. Eventually, you should move to a DFS infrastructure and get rid of login scripts and mapped drives. Keep that in mind when you are designing a login script solution for the Microsoft environment.
Removing the Novell Client:
If you have purchased the NDS Migrator tool, it can help you join workstations to the Active Directory domain, remove the Novell Client, redirect shortcuts, and fix imbedded OLE links inside Office documents.
An option is to suppress the Novell client by switching the Gina with this registry setting:
"HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\GinaDLL" as MSGINA.DLL instead of NWGINA.DLL
I don't recommend this as the workstation performance is impacted by the the Novell client. If you have the luxury to remove the Novell client, I would do so as part of the project. You may consider pre-deploying the removal agent. You can subsequently launch it as a shut-down script using the Local Security policy. This ties the forced reboot to a shut down event. Forced reboots are discouraged in most organizations.
Synchronizing
It's important to run frequent synchronizations in the object migrations. This keeps object attributes and group memberships synchronized. This requires maintenance as matching may break for some objects in the case of object moves or deletions. If you have multiple migration consoles such as in multi-national environments, use the import/export feature to keep the remote migration servers up-to-date.
Set-up a test environment
I always run through my migration scenarios in a lab. Then I use dummy data in the production environment before I move any live production data. Take the time to lay it out. I always learn something about the environment by replicating it in a lab. You'll need that lab as you get deeper into the project as well.
"There is always a way"
One of the great things about migrations, is that I always find a way to tackle even the most stubborn of issues. Be creative. You're an IT professional. This is what you get paid to do. I've never failed to get from point "A" to point "B" no matter how painful it was in between. Of course, your results may vary.

Reference:
http://moss-exchange.blogspot.com/2009/05/migration-of-novell-to-microsoft.html

Migrating AD into eDirectory, using OpenLDAP on OES

Preparing the LDAP Server

First, you need to configure slapd to get ready for the AD dump.
1. Edit /etc/openldap/slapd.conf
2. Find the following line:
include /etc/openldap/schema/core.schema
3. Add this after:
include /etc/openldap/schema/cosine.schema
include /etc/openldap/schema/nis.schema
4. Go to the line that starts with "suffix" and change to your AD structure:
suffix "dc=[basedn],dc=com"
5. Change the line that starts "rootdn" to your AD structure:
rootdn "cn=Manager,dc=[basedn],dc=com"
6. Save the file and exit.
7. Start slapd.

Building the Base LDAP Structure

1. Place the following into a file called base.ldif, and modify to your organization's needs.
dn: dc=[basedn],dc=com
objectclass: dcObject
objectclass: organization
o: [Your  Company]
dc: basedn
NOTE: The above line value for ?basedn? should match the first line's value for ?basedn?.
dn: cn=Manager,dc=[basedn],dc=com
objectclass: organizationalRole
cn: Manager
2. Import the file into LDAP.
ldapadd -x -D "cn=Manager,dc=[basedn],dc=com" -W -f base.ldif

Exporting Active Directory Data and Importing it into the LDAP Server

1. On a Windows domain controller, login as administrator.
2. Copy the Perl script samdump.pl and pwdump2 files to a temp directory.
3. Open a cmd window and change to the c:/temp directory.
4. Enter the following commands to extract the AD Users:
c:\temp\pwdump2.exe > passwd.txt
samdump.pl ?b dc=[basedn],dc=com passwd.txt users.ldif
You should now have a file (users.ldif) with all of your users in it.
5. Copy this file to your SLES server in the /root/ directory (for security).
6. Go back to your SLES server and import the AD users into the LDAP directory by entering the following command:
ldapadd -x -D "cn=Manager,dc=[basedn],dc=com" -W -f /root/users.ldif
At this point, all of your AD users, including their password hash, are in LDAP. Now you need to secure LDAP for eDirectory communication.

Securing LDAP for Import into eDirectory

1. Secure LDAP by encrypting your "rootpw" in your slapd.conf. We'll use "slappasswd" to do this.
slappasswd -s yourpassword
Here's the output:
{SSHA}i+RR9IAmrGDC0+RogacHrKNqUHVP1w7p
2. Copy that line and insert it into your slapd.conf (see the example).
3. Restart slapd.
If you do not have a CA, OES Linux creates one by default; or, you can create one as shown below.
4. Change directories to where you want to maintain these certificates - e.g., /etc/apache2/ssl.crt/
5. Create the certificates. We'll use the commands below:
openssl genrsa -des3 -out ca.key 1024
openssl req -new -x509 -days 999 -key ca.key -out ca.crt
openssl genrsa -des3 -out serverldap.key 1024
openssl req -new -key serverldap.key -out serverldap.csr 
6. Move the certificates into their own directory:
mkdir -p ldapca/private
cp ca.key ldapca/private/cakey.pem
cp ca.crt ldapca/cacert.pem
mkdir ldapca/newcerts
touch ldapca/index.txt
echo "01" > ldapca/serial 
openssl ca -policy policy_anything -in serverldap.csr -out / server.cert
7. To allow TLS-enabled connections add the following lines to /etc/openldap/slapd.conf, making sure to use the path to your new certificates:
TLSCertificateFile /path_to_your_certificates/serverldap.crt
TLSCertificateKeyFile /path_to_your_certificates/serverldap.key
TLS_REQCERT allow
Restart slapd
8. Add the following lines to /etc/openldap/ldap.conf ...
URI ldap://127.0.0.1
TLS_CACERT /path_to_your_certificates/serverldap.cert
TLS_KEY /path_to_your_certificates/serverldap.key
TLS_REQCERT allow

Importing LDAP data into eDirectory

1. Log in to iManager.

Figure 1 - iManager login
2. Expand eDirectory Maintenance and select the Import Convert Export Wizard.

Figure 2 - Running the ICE wizard
3. Select Migrate Data Between Servers.
4. Check "Run in Verbose Mode" and "Log Failed Records" (nothing's perfect ...)
5. Click Next.
6. Enter the IP/DNS name of the LDAP server and specify the secure LDAP port (636).

Figure 3 - Server data for ICE
7. Check Authenticated login and enter root and the password you set up earlier.
8. Click Next.
9. Specify the Base DN to search in the source tree and the extent of depth you want the search to go.

Figure 4 - Specifying the Base DN
10. Click Next.
11. Enter the IP/DNS name of the destination tree (eDirectory) and secure LDAP port of that server.
12. Check Authenticated Login and specify the FDN admin equivalent account and password.

Figure 5 - Destination tree data
13. Click Next.
14. Specify the container you want the objects placed.
15. Click Start to begin.
Verifying that Users were Imported
1. At the top of the iManager screen, next to Roles and Tasks, click View Objects and browse to the container you imported your users.
2. Click one of those users and select Modify Object.

Figure 6 - Modifying the user object
There it is - just like we had it in Active Directory.

Figure 7 - Modify Object screen
Note that this method does not migrate ACL's or user groups.

Example Scripts and .conf Files

Below are the scripts and example conf files you need.
# Start of /etc/openldap/slapd.conf
include /etc/openldap/schema/core.schema
include /etc/openldap/schema/cosine.schema
include /etc/openldap/schema/nis.schema
TLSCertificateFile /path/to/server.cert
TLSCertificateKeyFile /path/to/server.key
TLS_REQCERT allow
pidfile /var/run/slapd/slapd.pid
argsfile /var/run/slapd/slapd.args

database mydb
suffix "dc=myorg,dc=com"
rootdn "cn=Manager,dc=myorg,dc=com"
rootpw {SSHA}i+RR9IAmrGDC0+RogacHrKNqUHVP1w7p
# The database directory MUST exist prior to running slapd AND 
# should only be accessible by the slapd and slap tools.
# Mode 700 recommended.
directory /usr/share/openldap/ldapdata
# Indices to maintain
index objectClass eq
use strict;
use Getopt::Std;
use vars qw/ $opt_u $opt_g $opt_d $opt_s $opt_b $gidNumber $homeDirectoryBase $loginShell $basedn/;
# End of /etc/openldap/slapd.conf
samdump.pl
#!/usr/bin/perl
#samdump.pl

if (!getopts('uig:d:s:b:'))
{
 print "samdump: converts Win SAM dump to ldif\n";
 print "usage: [-b  basedn] pwdump-file\n";
  
 exit;
}
 $gidNumber = 100;
 $homeDirectoryBase = "/home/";
 $loginShell = "/bin/bash";

if ( $opt_b ) {
 $basedn = $opt_b;
} else {
 $basedn = "dc=Users,dc=net";
}

while ( <> ) {
 my ($name, $uidNumber, $lanmgr_hash, $nt_hash, $account_flags,  $lchange_time, $remainder) = split /:/, $_;
 next if $name =~ /\$$/; 
 print "dn: uid=$name,$basedn\n";
 print "objectclass: top\n"; 
 print "objectclass: account\n"; 
 print "objectclass: posixAccount\n"; 
 #posixAccount MUST
 print "cn: $name\n";
 print "uid: $name\n";
 print "uidNumber: $uidNumber\n";
 print "gidNumber: $gidNumber\n";
 #print "homeDirectory: $homeDirectoryBase$name\n";
 #posixAccount MAY
 print "userPassword: {lanman}$lanmgr_hash\n";
 #print "loginShell: $loginShell\n";
 print "\n";
}
# End of samdump.pl

Wednesday, April 6, 2011

Testing Out Load Balanced Mailbox Provisioning in Exchange 2010

Exchange 2010 introduces new functionality in which you can automatically assign a database to a user during the provisioning process. If a database name is not provided to the database parameter of the New-Mailbox cmdlet, a database will be selected automatically. Provisioned mailboxes will be created in a "load balanced" manner across all of the available mailbox databases in the same Active Directory site as the provisioning server – spreading the load, so to speak.
Load balanced mailbox provisioning is made possible by the Mailbox Resources Management cmdlet extension agent. The Mailbox Resources Management Agent is enabled by default, and can be managed using the *-CmdletExtensionAgent cmdlets.

Load Balanced Mailbox Provisioning in Action

I wanted to see how evenly the mailboxes are distributed amongst the available databases when importing a batch of new users from a CSV file. In my lab, I have three mailbox databases; DB1, DB2 and DB3. I created a total of 20 new mailboxes from a CSV file using the following steps:
First, create a password for all the accounts:
$password = ConvertTo-SecureString  -AsPlainText "P@ssw0rd01" -Force
Then, create a hashtable that will be used to track the total amount of mailboxes that are created in each database. Next, import the CSV file, create the mailboxes, and increment the database count where the mailbox is created:
$db = @{}

Import-Csv C:\mailboxes.csv | %{
  New-Mailbox -Name $_.name -Alias $_.alias  -Password $password -UserPrincipalName $_.upn | %{
    $db[$_.database] = $db[$_.database] + 1
  }
}

write $db
After the mailboxes are created return the hashtable with the total number of mailboxes created in each database. Here's the output from running the above code:

As you can see in the above screen shot, I provisioned 20 mailboxes that were created evenly across each database – 6 mailboxes were created in DB1, and 7 mailboxes were created in both DB2 and DB3. So, from this example we can tell that this new feature does a very good job of distributing the load when provisioning multiple mailboxes.

Excluding Databases from the Provisioning Process

You can permanently exclude databases from provisioning by setting the IsExcludedFromProvisioning property value to $true on a particular database. For example, to exclude DB2, we would run the following EMS command:
Set-MailboxDatabase DB2 -IsExcludedFromProvisioning:$true

If you want to temporarily exclude the database from provisioning, set the IsSuspendedFromProvisioning property value to $true, for example:
Set-MailboxDatabase DB2 -IsSuspendedFromProvisioning:$true

So, with this in mind, I suspended DB2 from provisioning and used the code from my previous example to create another 20 mailboxes from a CSV import file to see how the new mailboxes are distributed on each available database:

We can see from the output shown above that DB2 was not used, and we've got pretty even distribution of mailboxes across both available databases.
This may seem like a small improvement over Exchange 2007, but it obviously works very well and has already proven to be very useful in my mailbox provisioning scripts

References:
http://www.mikepfeiffer.net/2010/04/testing-out-load-balanced-mailbox-provisioning-in-exchange-2010/
http://www.mikepfeiffer.net/2010/02/provision-exchange-mailboxes-from-csv-using-powershell-advanced-functions/
http://www.mikepfeiffer.net/2010/06/rbac-database-scopes-in-exchange-server-2010-sp1-beta/

Tuesday, April 5, 2011

How to retrieve a list of Computer Accounts from Active Directory


$strCategory = "computer"
$objDomain = New-Object System.DirectoryServices.DirectoryEntry
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.SearchRoot = $objDomain
$objSearcher.Filter = ("(objectCategory=$strCategory)")
$colProplist = "name"
foreach ($i in $colPropList){$objSearcher.PropertiesToLoad.Add($i)}
$colResults = $objSearcher.FindAll()
foreach ($objResult in $colResults)
    {$objComputer = $objResult.Properties; $objComputer.name}
Save the script as GetPCNames.ps1 and run it in your Domain.
Now lets create the Computers.txt file that is used by the "Get-Content" cmdlet examples on this site.
.\GetPCNames.ps1 > "C:\MyScripts\Computers.txt"
I was able to create a list of 4,000 computer names within 3 seconds, results may vary…
  

Here is the explanation of how the script works and who better to explain it than "The Scripting Guy!"
We start out simply enough, assigning the value computer to a variable named $strCategory. We then use this line of code to create a new instance of the .NET Framework class System.DirectoryServices.DirectoryEntry. Because we didn’t specify any additional parameters when creating this instance our object reference $objDomain will automatically connect us to the root of our Active Directory domain. Neat, huh?

Incidentally, here’s the line of code we were talking about:

$objDomain = New-Object System.DirectoryServices.DirectoryEntry

After we connect to the domain we then need to create an instance of the System.DirectoryServices.DirectorySearcher class; that’s the object we’ll use to conduct our Active Directory search. After creating the object we then use these two lines of code to assign values to the DirectorySearcher SearchRoot and Filter properties:

$objSearcher.SearchRoot = $objDomain
$objSearcher.Filter = ("(objectCategory=$strCategory)")

As you probably figured out, the SearchRoot property simply tells DirectorySearcher where to begin searching. We want to search the entire domain so we set SearchRoot to the object reference $objDomain. In turn, the Filter property enables us to target a specific subset of the items found in Active Directory. Because the only thing we care about are computers, we tell the Filter property to bring back only those objects where the objectCategory attribute is equal to the variable $strCategory (which, as you recall, is equal to computer.)

Note. A detailed explanation of how to search Active Directory using Windows PowerShell falls way outside the scope of this little column. We will note, however, that the Filter property requires the LDAP search syntax; you can’t use the more familiar SQL-style syntax here. For more information, see the DirectorySearcher documentation on MSDN.

Our next step is to specify which attributes and attribute values we want our search to bring back. (If you don’t specify a so-called “property list” you’ll get back all the attributes and attribute values, which is not only more information than you need, but probably more data than you want to have clogging up your network.) These two lines of code add the name attribute to the list of property values we want back:

$colProplist = "name"
foreach ($i in $colPropList){$objSearcher.PropertiesToLoad.Add($i)}

We should point out that property lists need to be constructed as arrays. Why do we care about that? Well, suppose we wanted to get back both the name and the cn. In that case we’d have to assign the two values to $colProplist using syntax like this:

$colProplist = "name", "cn"

And yes, that is an array: in Windows PowerShell you can create an array just by assigning multiple values (with individual values separated by commas) to a variable.

After we’ve created an array our next chore is to use the PropertiesToLoad method to add those properties to our DirectorySearcher. To do that we set up a For Each loop to loop through all the items in the array, adding each item to the DirectorySearcher:

foreach ($i in $colPropList){$objSearcher.PropertiesToLoad.Add($i)}

Note. What’s that? You don’t know how to create a For Each loop in Windows PowerShell? If that’s the case, you should take a look at our Task-Based Introduction to Windows PowerShell.

Now, at long last, we’re ready to search Active Directory. To do that we call the FindAll() method, storing the data the search brings back in a variable named $colResults:

$colResults = $objSearcher.FindAll()

The only thing left to do now is set up a second For Each loop to loop through all the items (computers) in the collection $colResults. For each item (computer) in the collection we use this snippet of code to store the item Properties in a variable named $objComputer; we do that because, even though we asked for only the name, by default we also get back the computer’s ADsPath, something which can make our output difficult to read:

$objComputer = $objResult.Properties

If we don’t mind difficult-to-read output we could just echo back the value of $colResults and call it good:

$colResults

As soon as the computer Properties have been stashed in $objComputer we can then use this command to echo back just the computer name:

$objComputer.name

That’s going to give us output that looks something like this:

atl-dc-01
atl-dc-02
atl-dc-03
atl-dc-04


References:
http://www.powershellpro.com/computernames-activedirectory/149/

Wednesday, March 2, 2011

Exchange Server 2007: Bulk creation of mailboxes using Exchange Management Shell

Bulk creation of mailboxes (and the accompanying user accounts) in Exchange Server 2003/2000 involved some elaborate scripting effort. This task can now be done fairly effortlessly, thanks to the Exchange Management Shell (EMS). The Shell can very easily import/use CSV files saved from a spreadsheet or text editor and create the mailbox-enabled users. Here’s how.

Step 1 Create a spreadsheet

Create a spreadsheet (you can also use a standard text editor such as Notepad to create a CSV file) with the following columns. You can add more fields if you wish:
Alias,Name,UPN
Add data for new accounts in following lines/rows. Here’s what it’ll look like:
Alias,Name,UPN
User_One,User One,userone@yourUPNsuffix.com
User_Two,User Two,usertwo@yourUPNsuffix.com
User_Three,User Three,userthree@yourUPNsuffix.com
Save the file as CSV – let’s call it CreateRecipients.csv

Step 2 Enter a password

Now fire up the Shell (EMS) and issue the following command:
$Password=Read-Host “Enter Password” -AsSecureString
This will prompt you for a password. The same password will be used as the initial password for all your mailbox-enabled users.

Step 3 Import the CSV and create mailboxes

Next, issue the following command to import the CSV file and create the user accounts and mailboxes:
Import-CSV CreateRecipients.csv | ForEach {New-Mailbox -Alias $_.alias -Name $_.name -userPrincipalName $_.UPN -Database “Mailbox Database” -OrganizationalUnit Users -Password $Password}

How the Shell interprets the command

Here’s how the shell interprets the above command:
  • Import-csv CreateRecipeints.csv gets data from the CSV file.
    If you’re providing the complete path with spaces, you must enclose it in quotes. For example: “c:\My Scripts\CreateRecipients.csv”.
    - If you’re not running the command from the same directory (folder) where the CSV file is located, you will need to provide the complete path to the file.
  • - The | pipes the data from the CSV to the next command.
  • - foreach parses through each line in your CSV file, using the first row as a header. All the column headings/names get treated as field names.
  • - The New-Mailbox command, as you may already know by now, creates a new mailbox-enabled user.
  • - For each variable, you either enter a value at the command line (for instance, we’re using the value “Mailbox Database” for the Store), or you can pick up the value from your CSV file provided you have a column for it with a heading. For instance, for the -alias field, we use $_.alias – which tells the script to look for the column called alias in your CSV file and pick up the value from the current row or line.
    If you’re running the command on the same server where you want to create the mailboxes, you can simply use the Store name, e.g. “Mailbox Store”. To create mailboxes on another server’s Store(s), you can use either ServerName\Store, or ServerName\StorageGroup\Store, or even the GUID of the Store. How do you get those??? Use the Get-MailboxDatabase cmdlet.
  • - The -OrganizationalUnit field stands for (Active Directory) OU (or Container) you want to create the accounts in. If all the accounts you create from the CSV file will reside in the same container or OU, you can provide this at the command-line, as we did in the example above. Alternatively, you can include the OU/Container name in your spreadsheet/CSV file in a field – let’s say OU – and modify your command to say: -org $_.OU
    Note: Luckily you do not need to provide the distinguishedName of the OU or Container – simply the name of the OU or Container works.
  • - The -password field picks up the password from the variable called $password that we created earlier.
The New-Mailbox cmdlet allows you to enter a lot of attributes for each mailbox-enabled user. These are documented in the New-Mailbox cmdlet reference docs (Exchange 2007 | Exchange 2010), and also in the Exchange 2007/2010 online help. For each attribute you want to populate, add it to your spreadsheet/CSV file.

To create new mailboxes with settings based on an existing mailbox, use the TemplateInstance parameter, as shown in the following commands:
$Template = Get-Mailbox “Template Mailbox”
Import-CSV CreateRecipients.csv | foreach {new-mailbox -alias $_.alias -name $_.name -userPrincipalName $_.UPN -database “Mailbox Database” -org Users -Password $Password -templateinstance $Template}

NOTE: The TemplateInstance parameter is not supported in Exchange 2010

Reference:

http://exchangepedia.com/2006/11/exchange-server-2007-bulk-creation-of-mailboxes-using-exchange-management-shell.html

Adding Users to Sharepoint

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

Reference:
http://www.powershell.nu/2009/01/06/adding-users-to-sharepoint/