Wednesday, December 30, 2009

Microsoft Deployment Toolkit to aid in Netware to Windows Server Conversion

Just about a year ago I started messing around with the MDT 2008. I found it to be rather slick, despite the glaring crashes that happen frequently. Since then, MDT 2010 was released, and still it crashes. However, despite the rough edges, the results are very, very impressive. I haven't scratched the surface as to the power of how it can aid in any number of scenarios, but I have one in mind that will definitely be put to use.

I've created a task sequence that will install Windows Server 2008 SP2 (x86) if the hardware that installs the necessary roles for our file and print servers. What is so special about that? Well, it automatically partitions the drive, for one, then proceeds to do all sort of slick things like install applications, drivers, and custom scripts. If that sounds not so different than imaging, you're not far off. The MDT works in conjunction with Windows Deployment Services and can be used to capture images back to the WDS server. In fact, that is one of the recommended uses. For my purposes, however, it will deploy a new server preloaded with several applications that aren't "image friendly" thanks to their "tatoo" effect based on server name or other parameters. I've even added some custom Powershell scripts to the task sequence to automatically create a standardized folder structure for each branch office and create the shares with the proper permissions.

Once the new OS is loaded on the hardware, we're going to do a simple robocopy with a Windows XP workstation. This won't preserve any of the ACL's associated with the files, but in our environment that is part of what we're hoping for - to force the "crud" that has accumulated over the past 15 years to be sanitized a bit. Once the robocopy is complete, we simply power down the Netware server then re-IP the Windows server.

Printers will be pushed via Group Policy Preferences based on business logic using Item Level Targeting, and existing NDPS printers will be deleted from the machine based on a user login script that checks for a registry key that is also pushed via Group Policy preferences that has targeting based on the proper criteria.

Resources:

Monday, December 28, 2009

Sample Application using Groupwise Administrative Object API

Below is a copy of the source to a C# App that connects to a domain and creates a nickname for every user in the CSV. This code can be easily modified (and was in our case) to set the LDAP Authentication field in Groupwise to enable authentication via services such as Active Directory.

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.IO;
namespace GWAdmin
{

class Program
{
[STAThread]
static void Main(string[] args)
{
StringBuilder sbLog = new StringBuilder();
StreamWriter swLog = new StreamWriter(@"C:\alias-to-nickname.log");
try
{
AdminTypeLibrary.System GWSystem = new AdminTypeLibrary.System();
string strPath = @"\\fs\vol1\gw\dom\primary";
GWSystem.Connect(strPath);
List list = parseCSV(@"C:\aliasnohead-test.csv");

foreach (string[] strarr in list)
{

string poName = strarr[3];
string owner = strarr[4];
string nickname = strarr[1];
AdminTypeLibrary.Domain domain = GWSystem.Domains.Item("primary");
AdminTypeLibrary.PostOffice po = GWSystem.PostOffices.Item(poName, domain);
AdminTypeLibrary.User3 user3User = (AdminTypeLibrary.User3)po.Users.Item(owner, po, domain);
if (user3User.PrefEMailID != null)
{
user3User.PrefEMailID = null;
user3User.ClearAddressFormat();
user3User.ClearAllowedAddressFormat();
user3User.ClearInternetDomainName();
user3User.Commit();
sbLog.AppendLine(DateTime.Now + " :: Cleared PrefEMailID from user: " + user3User.Name);
}
else
{
sbLog.AppendLine(DateTime.Now + " :: PrefEMailID for : " + user3User.Name + " was blank. Skipping...");
}
AdminTypeLibrary.AdminObject ao = (AdminTypeLibrary.AdminObject)user3User;
GWSystem.Nicknames.Add(nickname, ao, ao.PostOffice, ao.PostOffice.Domain);
sbLog.AppendLine(DateTime.Now + " :: Added nickname: " + nickname + " for owner: " + owner);
}

}
catch (Exception ex)
{
sbLog.AppendLine(DateTime.Now + " :: " + ex.ToString);
swLog.WriteLine(sbLog.ToString());
}
swLog.WriteLine(sbLog.ToString());
swLog.Close();

}
public static List parseCSV(string path)
{
List parsedData = new List();

try
{
using (StreamReader readFile = new StreamReader(path))
{
string line;
string[] row;

while ((line = readFile.ReadLine()) != null)
{
row = line.Split(',');
parsedData.Add(row);
}
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}

return parsedData;
}

}
}

Groupwise Authentication to LDAP (Including Active Directory)

We recently wrote a utility using the Groupwise Administrative Object API to programmatically populate the LDAP Authentication field. This field is what is necessary to authenticate to LDAP services instead of relying on Groupwise authentication. Here is the jist of how it went down:

Obtain list of users in Groupwise
Ensure Groupwise users indeed had Active Directory Accounts
Use Powershell script to obtain "DistinguishedName" attribute from all users
Use utility written in C# to access the Groupwise Administrative Object API to loop through each user and post office and fill in their associated DistinguishedName into LDAP Authentication
Enable Post Office for LDAP. This meant placing our LDAP certificate in the SEARCH PATH (not the agent install directory as described in the documentation) in SYS:\SYSTEM for Netware and C:\windows\system32 for Windows.

Links:

Novell Official Documentation on LDAP Authentication for Groupwise 7 (Applicable to many recent versions)
Novell Administrative Object API Doc reference (See User.LDAPAuthentication. Says it requires Groupwise 7 SP3 or later)