Showing posts with label Active Directory. Show all posts
Showing posts with label Active Directory. Show all posts

2011-01-17

Windows 7/2008 Deployment - KMS and MAK Keys pt. 3

I would close up what we have learned from part 1 and part 2. During my work with the VMware Support on this case, one of the questions I asked, was is it possible to to inject a parameter into the customization process, but the only option was to import a full sysprep file. This would in essence break a good deal of the automation process, such as the rename of the OS to match the deployed VM name. So this was out of the question.

Unfortunately there was not much I could do here. So I rebuilt a new VM. But I had to take some certain precautions. Once your KMS is registered in the DNS and new OS connects to the network and gets an IP, it automatically looks up for a DNS record for the KMS server and will activate - which is exactly what I did not want.

The machine was started disconnected from the external network. I applied a MAK Key to the machine and then connected it to the network. Once a machine is activated with a MAK key, it will not try to contact a KMS server, so I was set.

So just to re-cap

  1. Build your VM
  2. Customize the OS - including your default profile settings
  3. Do not connect it to the network
  4. Install a MAK Key
  5. Connect to the network
  6. Activate the MAK key

The last part of the puzzle was how to change the MAK key to KMS for all the VM's that will be deployed from this template? This was actually the easiest part. In the Customization Spec you can enter a License Key, and yep you guessed it here you insert the MAK key.

Machine is deployed, the Customization Spec injects the xml (with the MAK key) into the VM, the vm is sysprep'ed (without a problem because you have 3 ReArms left) and when it comes back up automatically is activated with the KMS server.

A few things still puzzle me though. All of this worked - flawlessly on vCenter 4.0 - I did not have to go through this whole process with MAK and KMS and USD and BS! So did something change? Was there a change in the way the machines are customized from the previous version?

The deployment and templates were a bit icky after the upgrade.  I could not edit of my previous templates in vCenter - they all had to be re-registered VMware KB………

I also had another issue of not being able to deploy any templates at all (Windows / Linux) with customization until the vCenter Server got a kick in the butt and was restarted.

Small little things that do not add up. I am happy to say that I did manage to educate VMware support a bit on how this works, and in turn I learned a decent amount in the process of how the VMware deployment process works as well. All in all it was an educating experience all around. I was told that the information learned from this case will possibly be used in a VMware KB for all of our benefit.

On to solve the next problem. Hope you enjoyed this series of posts.

Windows 7/2008 Deployment - KMS and MAK Keys pt. 2

Continuing the problem from part 1.

Over the past 8 months this template has been updated with Microsoft security patches (released once a month) and during that time the template OS was activated - while connected to the network.

After the upgrade to 4.1, I noticed that I could no longer deploy a Windows 2008 R2 template with customization. (There were several issues here. In the beginning I could not deploy a template at all - but after a restart of the vCenter server and an SR submitted to VMware on the issue that was solved). But when customizing the the template - either with a manual Customization Spec or with a previous one we had been using for almost a year, the customization would not work. None of it.

Now this can become extremely annoying. Because once you get used to working with deploying a template with a customization spec, to do it manually takes time and can be cumbersome and prone to inconsistencies.The VM name would not be changed, network settings would not work, VM's were not being deployed with their vNIC's connected. There of course is a workaround to the whole problem, to do it manually but as I said before, this is not ideal.

Last week I finally found the reason this was happening, and partly for my own benefit (documentation) and to share the experience, let me explain what was happening.
When a Windows (7 or 2008) OS is activated with a MAK License Key, the OS is automatically set with a ReArm count of 3. This you you can see with a running the following command.

C:\Users\msaidelk>cscript c:\Windows\system32\slmgr.vbs -dlv
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.

Software licensing service version: 6.1.7600.16385
Name: Windows(R) 7, Enterprise edition
Description: Windows Operating System - Windows(R) 7, VOLUME_MAK channel
Activation ID: xxxxx-xxxxx-xxx-ad1e-7fe15931a8dd
Application ID: xxxxx-xxxxx-xxx-983e-d6ec3f16059f
Extended PID: xxxxx-xxxxx-xxx-132882-03-1033-7600.0000-2292010
Installation ID: xxxxx-xxxxx-xxx0249086468222046584484281164682806770
Processor Certificate URL:
http://go.microsoft.com/fwlink/?LinkID=88338
Machine Certificate URL: http://go.microsoft.com/fwlink/?LinkID=88339
Use License URL: http://go.microsoft.com/fwlink/?LinkID=88341
Product Key Certificate URL: http://go.microsoft.com/fwlink/?LinkID=88340
Partial Product Key: xxxxx
License Status: Licensed
Remaining Windows rearm count: 3
Trusted time: 04/01/2011 08:56:51

An OS which is licensed with a KMS License will look like this

C:\Windows\system32>cscript slmgr.vbs -dlv
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.

Software licensing service version: 6.1.7601.17105
Name: Windows Server(R), ServerStandard edition
Description: Windows Operating System - Windows Server(R), VOLUME_KMSCLIENT channel
Activation ID: xxxxx-xxxxx-xxx-97be-d11a0f55633f
Application ID: xxxxx-xxxxx-xxx983e-d6ec3f16059f
Extended PID: xxxxx-xxxxx-xxx-03-1037-7600.0000-0132010
Installation ID: xxxxxxxxxxxxx073476703659683995395732413372005
Partial Product Key: xxxHC
License Status: Licensed
Volume activation expiration: 253260 minute(s) (175 day(s))
Evaluation End Date: 01/12/2011 01:59:59
Remaining Windows rearm count: 1
Trusted time: 16/01/2011 23:27:12

Key Management Service client information
    Client Machine ID (CMID): a41eaf55-64a2-4509-ac85-2118804023f0
    KMS machine name from DNS: ilkms.maishsk.local:1688
    KMS machine extended PID: xxxxx-xxxxx-xxx-021634-03-1033-7600.0000-0132010
    Activation interval: 120 minutes
    Renewal interval: 10080 minutes
    KMS host caching is enabled


Once your OS has been activated through a KMS server - your ReArm count will be set to 1. If you try and change it back to a MAK key thereafter - the Rearm count will still be kept as 1.
So what happened? Somewhere along the way, my template was was activated with a KMS Key - which meant I only had 1 ReArm left.

During the deployment process of a VM with a Customization Spec, a number of files files are injected into the VM by vCenter.

Expanding C:\Windows\TEMP\vmw979D.tmp\guestcustutil.exe
Expanding C:\Windows\TEMP\vmw979D.tmp\imgcust-reboot.exe
Expanding C:\Windows\TEMP\vmw979D.tmp\sysprep\guestcustutil.exe
Expanding C:\Windows\TEMP\vmw979D.tmp\sysprep\sysprep.xml
Expanding C:\Windows\TEMP\vmw979D.tmp\sysprepDecrypter.exe

These files are then moved later on to c:\Sysprep
Moving directory 'sysprep' to 'C:'
vCenter takes the information passed from the the Customization Spec, decrypts the info and creates a new sysprep.xml file which is then in turn called from the customization process
Executing command C:\windows\system32\sysprep\sysprep.exe /quiet /generalize /oobe /reboot /unattend:C:\sysprep\sysprep.xml

Now how do I know all of this? A bit of reverse engineering. The deployment logs are located in C:\Windows\Temp\vmware-imc. The Sysprep logs are located here: C:\Windows\System32\sysprep\Panther

Two log files are created during the Sysprep process - setupacct.log and setuperr.log The first is the activity of the Sysprep and the second reports the errors that occurred.
When deploying a VM with an activated KMS license - I was getting these errors from the setuperr.log

2010-01-14 09:42:42, Error      [0x0f00a4] SYSPRP WinMain: Unable to parse command-line arguments to sysprep; GLE = 0x36b7[gle=0x000036b7]
2010-01-14 09:42:57, Error      [0x0f0043] SYSPRP WinMain:The sysprep dialog box returned FALSE
2010-01-14 09:43:04, Error      [0x0f0060] SYSPRP ParseCommands:Found unsupported command line option '/?'[gle=0x000036b7]
2010-01-14 09:43:04, Error      [0x0f00a4] SYSPRP WinMain: Unable to parse command-line arguments to sysprep; GLE = 0x36b7[gle=0x000036b7]
2011-01-12 11:18:48, Error      [0x0f0082] SYSPRP LaunchDll:Failure occurred while executing 'C:\Windows\System32\slc.dll,SLReArmWindows', returned error code -1073425657
2011-01-12 11:18:48, Error      [0x0f0070] SYSPRP RunExternalDlls:An error occurred while running registry sysprep DLLs, halting sysprep execution. dwRet = -1073425657
2011-01-12 11:18:48, Error      [0x0f00a8] SYSPRP WinMain:Hit failure while processing sysprep generalize internal providers; hr = 0xc004d307

Even though there was 1 left on my ReArm count this was not working. A quick syprep on the machine attested to that fact.

We will now close this series with how the problem was solved in Part 3.

2011-01-16

Windows 7/2008 Deployment - KMS and MAK Keys pt. 1

I have been dealing with an issue that has been bugging me for quite a while. It has to do with the deployment of Windows 7 or Windows 2008 R2 VM's and License Activation.

First let's describe the environment and situation. The whole infrastructure is at 4.1, vCenter and all ESX hosts as well. It was upgraded recently from 4.0. 7 months ago I created my templates - with all my customizations. Some of these customizations included different OS settings, menu sizes, toolbars etc. In order to copy all of these settings to the default profile, once upon a time all you had to do was to copy that current user profile to the Default User Profile, and subsequently every user than would logon thereafter would have all those settings defined. Starting with Windows 7 and 2008 (perhaps also Vista - I am not sure, we gave this version a skip) this was not the recommended way to this. There is a detailed Microsoft KB that explains the method - which is to Sysprep the machine and provide a setting in the unattend.xml file which will copy the profile. This can be done manually but that is not recommended. You should use the WAIK. This tool is available from Microsoft.

After installing the software you attach a Operating System Image and create an answer file. In that answer file you can search for the Copy Profile option and set:

<CopyProfile>true</CopyProfile>

My first problem I ran into then was that I was not aware of the fact you can only Sysprep a machine 3 times, thereafter you will not be able to do it any more. This of course led me to a problem of after making changes to the VM and Sysprep'ing again and again and again - I could no longer continue with this Template (Thank you VMware for snapshots!!).

Failure occurred while executing 'C:\Windows\System32\slc.dll,SLReArmWindows', returned error code -1073425657

There is a solution to this issue which can avoided by adding an additional flag to the unattend.xml file <SkipReArm>1</SkipReArm>.

The Activation grace period is typically 30 days. It begins after Windows Setup finishes and the computer boots for the first time. While there is no limit to the number of times that the Sysprep command can run on a computer, there is a limit to the number of times Windows can be rearmed. Typically, a system can be rearmed only three times. Using this setting enables you to run the Sysprep command multiple times without resetting the activation clock.

And now I finally had my template customized, and ready for deployment.

Now over the past 8 months the we have implemented a Microsoft KMS server. Before that let us go into what has changed since the days of XP/2003 in terms of licensing/activation. With Windows 2003/XP organizations were provided with a VL (Volume License) Key. That meant I could put the serial number in the image / template / Sysprep file for each and every machine. Once installed there was no further action needed. Starting with 2008/Windows (remember we skipped Vista) we were provided with 2 different License Keys, a MAK key and a KMS Key.

Frequently Asked Questions About Volume License Keys. A MAK key is one that you add to the OS and that has to be activated with Microsoft. This can be done over the internet or with the VAMT (I will not go into how to provide a proper licensing mechanism for your OS's in your organization). This is not an automatic process and for a small amount of OS's it is quite suitable. Christian Mohn has created a good explanation of how to use this tool. But when you are talking about hundreds and thousands of operating systems, this does not scale well. Also not always do you want to open your firewall to allow each and every computer to activate with a Microsoft Server somewhere "out there". Therefore Microsoft introduced the KMS (Key Management Server). It is a role that you can install on Windows Server 2008 which will act as your activation server for all OS's in the organization. There is a record in the DNS that is created which each new OS will look for by default and if found will activate the OS - automatically. Much better for a bigger environment.

We will continue into part 2 of this series with the issue at hand.

2010-09-29

Host Crash because of ESX Active Directory Authentication

I was subscribed to this thread and received an update today that I must have missed previously, with an issue much more serious than the one that the thread was originally started with.

Previously, I posted an article to explain how to Integrate ESXi into Active Directory. After the integration logging onto a host with your domain credentials can cause the host to crash. The issue occurs when the user logging into the ESX host with their Active Directory credentials is a member of more than 30 Security Groups.

The issue has been confirmed with happening with the user being a member of as little as 23 security groups as well.

The ESX Host throws an error and reboots (PSOD) and reboots. The thread owner has a ticket open with VMware and according to the information there engineering are working on the issue.

Below are Screenshots taken from the thread

imageimage

I ran a quick check to how many groups my AD account is a member of (Powershell of course)

Get-QADUser msaidelk | Get-QADMemberOf -ErrorAction Continue | where {$_.GroupType -eq "Security" } | Measure-Object | Select-Object -Property Count | Format-List

Count : 45

I have tried to re-create this on my standalone host but have not experienced this problem.

Has anyone else encountered this issue?

2010-07-16

Quest ActiveRoles Management Shell for AD-1.4

Quest just released a new version of there amazing Active Directory Module - Version 1.4

Here is Dmitry’s Post about the release:

There are many new Cmdlets available here are some of the details from the release notes

1.1. New cmdlets

• Get-QADLocalCertificateStore
• New-QADLocalCertificateStore
• Remove-QADLocalCertificateStore
• Get-QADCertificate
• Where-QADCertificate
• Add-QADCertificate
• Import-QADCertificate
• Show-QADCertificate
• Edit-QADCertificate
• Export-QADCertificate
• Remove-QADCertificate
• Remove-QADPrivateKey
• Get-QADCertificateRevocationList
• Add-QADCertificateRevocationList
• Import-QADCertificateRevocationList
• Export-QADCertificateRevocationList
• Remove-QADCertificateRevocationList
• Get-QADPKIObject
• Publish-QADCertificate
• Unpublish-QADCertificate
• Publish-QADCertificateRevocationList
• Unpublish-QADCertificateRevocationList
• Add-QADProxyAddress
• Set-QADProxyAddress
• Remove-QADProxyAddress
• Clear-QADProxyAddress
• Enable-QADEmailAddressPolicy
• Disable-QADEmailAddressPolicy
• Set-QADProgressPolicy
• Get-QADProgressPolicy
• Set-QADInactiveAccountsPolicy
• Get-QADInactiveAccountsPolicy

1.2. New parameters

1.3. Multi-value SearchRoot Parameter

The data type of the SearchRoot parameter has been changed to support a search within two or more containers at a time. This parameter now accepts an array of objects rather than a single object as it was with earlier versions. This makes it possible for the cmdlet to search multiple containers identified by the SearchRoot parameter value. For example, you can supply an array of strings each of which
represents the canonical name of a certain container, to retrieve objects from all of the containers specified.

2. Bugs fixed

[48939] Cannot work with object that contain round brackets in their names in Proxy mode.
[48941] Command 'Get-QADRootDSE | Format-List *' fails in Proxy mode.
[112742] Command 'Get-QADGroup -ContainsMember <member id>' doesn't work in Proxy mode.
[112870] Command 'Get-QADGroupMember 'Domain Users' | Get-QADUser' renders significant memory leak in Direct mode.
[113168] Set-QADUser can't work with input object of type 'inetOrgPerson'.
[115955] New-QADObject can't create objects with special symbols in name in Proxy mode.
[117478] Cannot set AD LDS user as owner for another AD LDS user.
[114381] ObjectAttributes parameter in New-QAD* cannot be passed by pipeline.
[116033] Get-QARSApprovalTask throws exception if task with status ‘Canceled’ present in result.
[115106] Add-QADGroupMember throws error when trying to add user to it's primary group.
[116484] New-QADObject should continue its execution with -ErrorAction:Continue if the object already exists.
[104161] 'Remove-QADObject -DeleteTree' should work properly for objects in Win 2008 R2 Recycle Bin.
[121356] Set-QADUser works incorrectly with import of multivalued attributes.

As you can see from the release notes there a multitude of new features released.

I find these Cmdlets a necessity in my day to day work in Management of Active Directory.

Download Links Below

ActiveRoles Management Shell for Active Directory 32-bit

ActiveRoles Management Shell for Active Directory 32-bit - Zip

ActiveRoles Management Shell for Active Directory 64-bit

ActiveRoles Management Shell for Active Directory 64-bit - Zip

ActiveRoles Management Shell for Active Directory - Administrator's Guide (PDF)

ActiveRoles Management Shell for Active Directory - User Help Guide

The Zip files include the Build History (Release Notes) Administrator's Guide and the Help Guide.

I am personally looking forward to kicking the tires on this one!

2010-07-15

ESXi 4.1 Active Directory Integration

The previous post about what was new in vSphere 4.1 was a general overview with some slide shots. For all ye of little faith thinking that I was only going to post those screenshots with no details Nuh-Uh! 
I prefer to lay down the basics with screen shots - and then go into the details. I mean you do have to cater for all spectrums of the public from basic to advanced.

So without further a due - let's go into how you can add you ESX/i server into the domain.

But why would you?

Well actually there is a very simple reason - Security. One of the biggest problems it providing a single mechanism to authenticate yourself with the same credentials to all components of your infrastructure. With vCenter it is easy - since it is a Domain Member - all authentication is done through active directory. But going directly into the ESXi host - that is a different story all together you will have either authenticate with Linux credentials - or configure the authentication to be done by active directory - but for that you need a valid Linux user on the ESXi box.

(** Small note - since the future version of ESX will only be ESXi I have decided - that I will be using ESXi exclusively in my posts - unless the issue is directly related to the full ESX version)

There are 4 ways of doing this

  1. ESXi Host directly
  2. Host Profiles
  3. CLI
  4. Script

Before starting you need to make sure of a few things

You have correct time synchronization with between your ESX host and the Domain controllers - this is a must. Kerberos is extremely picky when time difference off.

You have proper DNS resolution from the ESX Host, and that the name servers are correct.

Also your ESX host has to have a FQDN - for example:

Hostname: esx1
Domain: maishsk.local
FQDN: esx1.maishsk.local

On the ESXi Host


Log into your host directly - NOT through the vCenter. The documentation says

image

I have found that if you do this on the vCenter server - the Properties option is grayed out. and you cannot make the change.

2010-07-15_0923

Configuration Tab -> Authentication Services-> Properties

2010-07-15_0924[3]

Enter domain name (in one of two ways) maishsk.local (Default computer location) or maishsk.local/Computers/ESX (for putting the computer account in the ESXi OU under the computers container)

2010-07-15_0933

Click Join Domain - and you will be asked for domain credentials - this user has to have permissions to add computers to the domain. Format is either administrator@maishsk.local or MAISHSK\administrator or just plain administrator

Once that is done - you can see on the Active Directory Users and Computer Console that you now have a new computer account.

2010-07-15_0933_001

To allow the the user/group access to the ESXi host your will have to define the permissions.at the appropriate level.

In the case I gave the Domain Admins full access to the Host

Permissions -> Add Permission -> Administrators ->Add

2010-07-15_0934

From the Server field choose your domain and search for your user/group (reminds anyone of vCenter?)

2010-07-15_0935

2010-07-15_0936

The user can now login with their domain credentials

2010-07-15_0941[3]

2010-07-15_1006

*** Update ***

I would like to also point out the what Raphael Schitz posted on his blog regarding the ESX Admins group and how this group automatically has access to the host just added to the domain. Thanks for pointing this out

By default, the ESX host assigns the Administrator role to the “ ESX Admins ” group. By default, the ESX host assigns the Administrator role to the "ESX Admins" group. If the group does not exist when the host joins the domain, the host will not assign the role. If the group does not exist When the host joins the domain, the host Will not assign the role. In this case, you must create the “ESX Admins” group in the Active Directory. The host will periodically check the domain controller for the group and will assign the role when the group exists . In this box, you must create the "ESX Admins" group in the Active Directory. The host Will periodically check the domain controller for the group and Will assign the role When the group exists.

2010-07-01

Updating pictures for Users in AD - pt. 2

The last sentence in my previous post on Updating Pictures for Users in AD was

Now the only part hat needs to be taken care of - is getting a proper image from HR in the correct size. Maybe we will find a Powershell script to take care of this :)

So here it is.

This can be done with ImageMagick

Once you have unpacked the Zip file (to c:\temp\ for example)

Function convert-pics {
	$cmd = "C:\temp\ImageMagick-6.6.2-5\convert.exe"
	Get-ChildItem C:\temp\pics | ForEach-Object { 
	$newname = "C:\temp\pics\test\"+$_.Name
	$filename = $_.Fullname
	invoke-expression "$cmd $Filename -resize 96x96 $newname"
	}
}

convert-pics

 

Line 2. Define the command you will run

Line 4. Save the files to different folder

Line 6. Run the command to convert the pictures to the correct size.

And uploading them all to Active Directory

 

Get-QADUser -sizelimit 0 -IncludedProperties  thumbnailphoto |  ForEach-Object {
	if ($_.thumbnailPhoto -notlike "FF*") {
		$filename = "C:\temp\pics\test\"+$_.SamAccountName+".jpg"
		if (Test-Path $filename) {
			$photo = [byte[]](Get-Content $filename -Encoding byte)
			Set-QADObject -identity $_.SamAccountName -ObjectAttributes @{thumbnailPhoto=$photo}
		}	
	}
}	

 

Line 1. You have to specifically define the thumbnailPhoto attribute to be retrieved

Line 2. Check if the user already has the attribute populated already - if not then continue

Line 3. Set the variable of the filename

Line 4. Check for the file - if it exists then continue.

2010-06-22

Get-AllDomainControllers Function

Sometimes you would like to run a query against all DC’s in your forest. For example today – I was looking a specific error on the System Event Logs.

Here is a quick way to get all the DC's in the forest adapted from Marcus Oh’s blog.

# ==============================================================================================
# NAME: Get-AllDomainControllers
# 
# AUTHOR: Maish Saidel-Keesing
# DATE  : 22/06/2010
# 
# COMMENT: 	Will collect all Domain controllers, set the list as the $alldcs variable
#			and output as list 
#
# ==============================================================================================

function Get-AllDomainControllers{
	
	$myDomain = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
	$script:alldcs = $myDomain.Forest.Domains | ForEach-Object { $_.DomainControllers } | `
		Select-Object -Property Name | Sort-Object -Property Name
	$alldcs
}


### Entry point to script
Get-AllDomainControllers


From there to get the event I wanted was easy

$alldcs | ForEach-Object {
Get-EventLog -LogName System -ComputerName $_.Name -source KDC -EntryType Error -Newest 10 | where {$_.EventID -eq 27} |  select-object TimeGenerated,MachineName,message
}

2010-06-20

Virtualization Domain Controllers - #2

I received a number of comments on my previous post and offline as well I want to clear up some things regarding the previous post.

I am not against virtualizing domain controllers - not at all. I am against trying to P2V a domain controller. It seems that was not clear enough from the last post. I do still advise that if your risk analysis - you should do that before virtualizing your domain controllers (or anything else for that matter) comes out that it is more cost effective to keep one Physical DC then do so. There are a number of reasons to go either way - it all depends on your environment and what you are willing to risk.

It will save you so much headache and anguish - if you would just promote a new clean VM to a Domain controller.

Now lets go into a a good reason (or two) why you should actually virtualize your domain controllers

  1. Domain Controllers do not need that many resources

    image 
    Of course there is a whole science behind this and a good amount planning guides out there - you can see that a domain controller does not need that many resources. It has relatively stable RAM usage (loading the AD database into RAM is mostly what it does) - CPU usage will depend on the authentication traffic - same with Network and Disk IO.
    The resource usage can be predicted very well - so you can plan the resources for such a Machine.
  2. You should have more than one - if you don't then you are not doing your job correctly. But that means if your one of your Domain controllers fail - because your ESX host failed - then you are still up and running - because you have another DC running (either on an ESX host or physical).
  3. Testing purposes. You need to prepare your AD Schema for the upgrade to Exchange 2010. Even though the schema extension is a Microsoft product, and has probably been tested countless amount of times with all levels of AD Domains. But of course every domain is different. And no matter how many times Microsoft have tested it - it has not been tested on my domain, in my environment, with my applications.
    So for this I would need to test the upgrade. So what better way to do it on a replica of my Production Environment.
    All I need need to do is to power off the DC, copy the VM to a closed lab environment, power them both back on, fix up a whole bunch of stuff to get it working in the lab without access to the outside world, and hey I have a full replica of my production domain that I can test.

So as you can see there are benefits to virtualizing your DC's - just a few of them above.

What other benefits would you add to the above list? I would appreciate your comments.

2010-06-17

Updating Pictures for Users in AD

I came across a nice article last week regarding pictures for User accounts in an Active Directory environment

First let describe the issue at hand. Every now and again, my manager gets an email saying,
"Why don't I see the picture of xxx when I open up his mail?"

image

And shortly thereafter I get an email asking the exact same question.

Well the answer is always give is that up until Exchange 2003 - there was no option of adding a picture to GAL (Global Address List) - and even if you did you had to jump through hoops to get that picture to appear in Outlook on every computer.

Starting with Outlook 2010 - that feature is built-in so it makes life a lot easier.

Now of course this does not only work with Outlook - but with everything that uses this GAL - for example OCS, SharePoint ….

So how do you get the picture into the GAL? Simple put the picture into the Users attribute in Active Directory.. :)

Uhmmm …. Simple? How do you do that?

With Powershell it is, which leads me to the article I came across on Mike Pfeiffer's Blog which shows you how. He is using the native AD Cmdlets - but that of course only works if you have a Windows 2008 Domain Controller or the Active Directory Web Services installed in your domain.

And if not?

I used the Quest Active Directory Powershell Cmdlets to do the job.

#Convert the image to Bytes
$photo = [byte[]](Get-Content C:\temp\maish.jpg -Encoding byte)

#Set the Attribute on the User
Set-QADObject -Identity -ObjectAttributes @{thumbnailPhoto=$photo}


Next to come up - what is the size of the Thumbnail that should be put there?

Recommended is no larger than 96x96 pixels and is limited to 10Kb in size, anything bigger will not work.

How does this affect the Active Directory Database?

Well adding in more information will make the DB grow - but for 1000 Users x 10KB you get 10MB so that addition is negligible IMHO - User certificates that are stored in AD are about the same size. Add to the fact that it is a one time synch - because most of this data is static anyway.

You will have make sure that the attribute is replicated to the Global catalog in the Schema

image

Now the only part hat needs to be taken care of - is getting a proper image from HR in the correct size. Maybe we will find a Powershell script to take care of this :)

2010-06-13

Virtualizing Domain Controllers

One of the frequent questions that come up on the forums is,
"How do I convert (P2V) my Windows Domain Controller (or SBS Server)?"

Let me first start with the following statement.

DON'T!!!!


Now that I have that off my chest - lets explain why and provide some references to back that up.

A Domain Controller could possibly be - and probably is - one of the most important computers on your network. Almost everything relies on Active Directory:

  • Authentication
  • Mail
  • Web
  • File Access
  • etc. etc.

If your Domain controller is not functioning - then rest assured - slowly but surely a lot of other things will stop working shortly thereafter.

I was reading a good blog post from the Active Directory Team on their blog  - How to Virtualize Active Directory Domain Controllers (Part 1). This is a Hyper-V centric article - but it is relevant to VMware as well .I do advise giving the full article a good read.

This is what I have taken with me from the above article.

  1. In most environments there is no reason not to virtualize your Domain Controllers. If they are only being used as Domain Controllers (and not File Servers, DHCP, Web Servers) then unless you have a very large or extremely busy environment your DC's will not need an extravagant amount of resources so it can run very nicely as a virtual machine.
  2. I would always, ALWAYS, leave at at least one physical server running as a domain controller on the network. The reason being, if your virtual infrastructure depends on your Active Directory infrastructure - and it always does then if your DC's are not available due to your Virtual Infrastructure being down, or your storage being down, then you will have a serious chicken and egg situation - with not being able to easily bring up the storage or the Virtual infrastructure because they are dependant on DNS / Active Directory and that cannot come up because the the storage / Virtual infrastructure is not available.
    Jason Boche posted an article last week describing a situation where he had a network component fail - which brought down his NFS storage. One of the VM's on that storage was his Domain Controller. Once the failure was fixed, he could not bring up the NFS datastores - because they were relying on Name Resolution - and the DC was a VM on the NFS datastore, which could not be mounted, because there was not Domain Controller. As I said Chicken and Egg. True there are ways to get around it but I sleep better at night spending that extra amount of money on a physical server for a domain controller.
  3. Time Synchronization. A  domain controller should always be synchronized with an external time source. do not rely on the internal VMware Tools.
  4. Do not stop or suspend Domain controllers. Leave them on or power them off.
  5. Do not restore a Domain Controller from a snapshot. You will run into USN Rollback problems.
  6. Back up you Domain Controller the same way you would back up a Physical Server, be it NTBACKUP, Windows Backup and Restore (for Windows 2008 and Up) or a 3rd party backup client.
  7. If you try to P2V  a DC you will most likely run into a USN Rollback problem - Knowledge Base Article.
  8. The Easiest way to migrate a Domain Controller is to install a new VM, DCpromo the VM as a new DC and then remove the old one. The process of migrating the data in Active Directory from one computer to another is really simple and completely taken care of by Windows, so do not try and complicate things.
  9. VMware KB 1006996 - Virtualizing existing domain controllers.

2010-05-14

Set a Time Limit on Group Membership

One of the most surprising things that Microsoft have not yet provided in Active Directory management - is allowing you to set a time limit on assigning membership of a user to a group.

Let me explain the use case for this kind of feature.

You have resource (be it a file, web site - what ever). You want to assign the permission to a user, but you only want to do it until the end of the day, of for the next hour. Unfortunately there is no functionality like that is Active Directory. Sure you can set expiration on an account - but not on group membership.

I was asked to provide a solution to this problem for a specific use-case problem. I would like to point out that a great part of the original logic of this script was done by a fellow team member - who is a great scripter - So thanks Natan. I did change the script in order to accommodate a few more features.

The users were not allowed to be members of this group for more than 7 days, and they should be removed automatically after that period

So the logic was as follows:

The user would call in to the helpdesk, and get added to the group. Once a day, the members of the group would be checked and compared to a list of users in a file (from the previous run). If they were there, then their Countdays field in a file would be reduced by one (until reaching zero). If they were new additions to the group (and they would not be in the file) then add there info with a default counter. If their record had reached zero - then remove them from the group.

Here is a more graphical explanation

image

Here is the script

# ==============================================================================================
# NAME: erase-after-days.ps1
# 
# AUTHOR: Maish Saidel-Keesing
# DATE  : 12/05/2010
# 
# COMMENT: script erase-after-days is for erasing users from a security after predefined number of days
# Changed by Maish Saidel-Keesing (12/05/2010)
# Added 3rd field SubmittedBy, changed logic to Compare-object
# Requires Quest.ActiveRoles.ADManagement Snapin
# ==============================================================================================

# Check for Snapin
 if ((Get-PSSnapin Quest.ActiveRoles.ADManagement -ErrorAction SilentlyContinue) -eq $null) {
 	add-PSSnapin  quest.activeroles.admanagement
	}

#Establish Connection	
Connect-QADService -service maishsk.local   	

#Define default number of days
$days = 7

$GroupName = "My_time_limit_group"	
$infile = "\\server\time_limit.txt" 

$GResults = Get-qadgroupmember $GroupName
$in1 = Import-Csv $infile

# Create variable to look for matches
$compare = @(Compare-Object $in1 $GResults -Property "DN" -IncludeEqual | `
	Where-Object {$_.SideIndicator -eq "==" } | select DN)
# Variable to hold new additions to Security Group 
$nomatch = @(Compare-Object $in1 $GResults -Property "DN" -IncludeEqual | `
	Where-Object {$_.SideIndicator -eq "=>" } | select DN)

#Run for each object that is already in the Security Group
foreach ($object in $compare) {
	$record = ""
	$record = $in1 | Where-Object {$_.DN -eq $object.DN}
	if ($record.CountDays -gt 0) {
		$record.CountDays -= 1
		if ($record.SubmittedBy -eq "" ) {
			$record.SubmittedBy = "Script"
		}
	} else {
	#If member counter is equal to 0 then remove from Security Group
	Remove-QADGroupMember -Identity $GroupName -Member $record.DN -WhatIf
	}
}
$in1 = $in1 | Where-Object {$_.CountDays -ne 0 }

#Run for each new user that was detected
	if ($nomatch.Count -gt 0) {
	$out1 = @()
	foreach ($object in $nomatch) {
		$row = "" |select DN,CountDays,SubmittedBy
		$row.DN = $object.DN
		$row.CountDays = $days
		$row.SubmittedBy = "Script"
		$out1 += $row
		}
	$in1 += $out1
	}
	
$in1 | export-csv -Path $infile -Force -notype
Disconnect-QADService


Line 13 Check for Quest Cmdlets

Lines 18-28 Define the variables

Line 30 Compare both variables and find the instances where the DN field in each variable matches - the results that is received from a match is "==". The -includeEqual switch will show the matches (otherwise you do not get any output)

[23:54:55] ~> Compare-Object hello hello -IncludeEqual

InputObject                                                 SideIndicator
-----------                                                 -------------
hello                                                       ==


Line 34 Compare both variables and find the instances where the DN exists in the Security Group but not in the file - which means it is a new user.

Line 38-49 First we work on the matched users. Here we retrieve the matching record and perform the logical query. If the days are larger than 0 - decrement. If not (which means that the user has been in the group for 7 days) then remove them. All of this is updating the $in1 variable

Line 51 Recreate the variable without the entries that will be removed

Line 54 Check for the number of items in $nomatch - if there is nothing then there is nothing to run

Line 56 Now we add the new users from all $nomatch variable.

Line 63,66 Combine today's results with $in1 and export the file back out.

The script runs daily as a scheduled task.

Now of course you could always expand on this and add functionality - such as automated email notification before user is removed, I am sure that You can expand the also to have this monitor multiple groups.as well.

Now all I have to wait for is for Microsoft to add this functionality to Active Directory

2010-04-28

Monitor AD Replication Status with Powershell

Do you know the feeling?

You have 40 domain controllers located in 20 different locations - with a multitude of child domains and children of those child domains, on all sides of the globe (yeah I know a globe does not have sides….), with different people at different levels of expertise managing these DC's? Sound familiar?

And for some reason someone went on vacation and forgot to clean up a movie that they put on the DC's C: drive - because they had nowhere else to put it? (well I am joking of course - but the reasons for disk space running out could be for multitude of reasons).

And the C: drive has no more free space.

And therefore the DC's stops responding properly.

And your start getting replication errors between the Domain Controllers.

So do you know the feeling??

Now of course you could have someone (or something monitor your logs for you - but not necessarily would you catch the replication issue - because you would have to monitor more than just one DC).

Well thanks to Microsoft there is small tool which will give you the replication status and if you would like it can do a whole lot more than that, but for this example the replication status will suffice.

Repadmin - and if you have not used it before then I suggest you get to know the tool.

repadmin.exe /showrepl * /csv

Ok .. Whoopee! And now what do I do with that info? Well you could:

  1. open it in Excel and
  2. filter out all the values that have 0 failures
  3. and then see where the issues are

That would be nice… but not automated!!

What if you could get the data, filter out to retrieve only what you wanted (which would be all the failures) and send it to an admin by mail. And to make your life complete (just kidding), have this run on a regular schedule?

Here you are.

# ==============================================================================================
# NAME: Check-Replication
# 
# AUTHOR: Maish Saidel-Keesing
# DATE  : 27/04/2010
# 
# COMMENT: Will check the replication status and if there are failures will send an email to the
# Assigned Addresses.
# ** Requires Repadmin from the Windows resource Kit accessible in the default path **
# ==============================================================================================

$from = "Replication Status<maishsk@gmail.com>"
$to = "Maish<maishsk@gmail.com>"
#Collect the replication info

#Check the Replication with Repadmin
$workfile = D:\software\USB_Tool_Kit\Tools\repadmin.exe /showrepl * /csv 
$results = ConvertFrom-Csv -InputObject $workfile | where {$_.'Number of Failures' -ge 1}


#Here you set the tolerance level for the report
$results = $results | where {$_.'Number of Failures' -gt 1 }

if ($results -ne $null ) {
	$results = $results | select "Source DC", "Naming Context", "Destination DC" ,"Number of Failures", "Last Failure Time", "Last Success Time", "Last Failure Status" | ConvertTo-Html
	} else {
	$results = "There were no Replication Errors"
}

Send-MailMessage -From $from -To $to -Subject "Daily Forest Replication Status" -SmtpServer "smtp.maishsk.local" -BodyAsHtml ($results | Out-String)


Line 17.
Run the command and put it into CSV format

Line 18. Convert the results from the variable into a variable and filter them

Lines 20-24. If the results are not empty (which means you have errors) then apply some formatting to the output and convert that output to HTML. If there were no errors then set the variable to show that fact.

Line 26. Send the results by email

So from going from lines and lines of this

image

to this - which I can get in my inbox every 4 hours because it is now running as a scheduled task.

image

or this if all is fine and dandy

image

Hope this is useful to someone!

--UPDATE--

I updated the script above to remove the use of a temporary file - it was not necessary - everything can be saved into variables and clean up some logic.

2010-04-22

IBM IMM integration into AD

This one has nothing to do with Virtualization as such.

All new IBM servers from the M2 series and up have a IMM IBM Integrated Management Module. For you HP'ers - it is the same as ILO.

The same as ILO the IMM comes in two modes - the free integrated version which does not allow Remote Presence (remote console control) and the full version which requires a Virtual Media Key (a physical component on the Motherboard) at an additional cost

By default the IMM comes up with with a DHCP Address.

Default Credentials - USERID/PASSW0RD (the 0 is a ZERO)

So instead of creating a local user for each and every user that was supposed to connect I wanted to configure it for AD authentication. I wanted to allow a group of users to manage the server.

So here is the process.

First we go to the Login Profiles Section and change the default from Local only to
LDAP first, then local. Don't forget to save the settings..

image

We then choose the Network Protocols Section

image

and go to the Lightweight Directory Access Protocol (LDAP) Client section

image

Lets go through each of the the Sections

image

Here you put in the FQDN of you domain controller and the port that DC is listening on.

For example: dc1.maishsk.local - 389

image

Root DN - here you will set the DN where you will search for your group.

UID Search Attribute - What attribute you will use to search on.

Binding Method - This will use the sAMAccountName Attribute

Enhanced role-based security - This I left disabled because the use of this feature requires a lot more intense configuration

Group Filter - Here you use the name of the group that you want to grant access
The format should be CN=<groupname> (and yes - it does not have to be a security group - DG's work as well)

Group Search Attribute - memberOf - this is to see that the user is a member of the group.

Hope you can all make some use of this.

2010-03-19

Distribution and Security Groups

I was asked to day at work, "What would be the quickest way to add all of the members of a Distribution Group to a Security Group?", the reason of course being because you cannot assign permissions to a Distribution group.

My answer was, "To script it."

And I never would have thought how easy it would be

Get-QADGroupMember "My_DG_GROUP" | Add-QADMemberOf -Group "MY_SG_GROUP"
 
  • Amount of time spent on Task: 30 seconds
  • Financial investment in that task: Depends on how much you make per hour :)
  • The reaction I got for doing something so complicated "so quickly": PRICELESS!!!!!

2010-02-17

ESX 4.0 Active Directory Authentication

There are numerous posts about how to use Active Directory to authenticate your ssh logins to your ESX servers.

Jason Boche,Travis Laird, Geert Baeke

The idea is pretty simple

  1. Configure the ESX server with esxcfg-auth as in the above posts
  2. Add the desired users locally on your ESX Server
  3. Login away

But….

Once this is enabled  all authentication will be done against Active directory – INCLUDING THE root USER

Jason mentioned this on his post

Warning:  One thing to watch out for would the existance of a root account in AD in which you are not the owner of.  By implementing AD authentication, a root account in AD is going to be granted root level Service Console access on the ESX host!  Take the necessary precautions here.

Travis did as well and provided a solution as well

If you are not using root login through SSH and you want to exclude the root user login from attempting Active Directory authentication, modify the /etc/pam.d/system-auth file and add the parameter minimum_uid=1 to the following line so it reads:

auth sufficient /lib/security/$ISA/pam_krb5.so use_first_pass minimum_uid=1

Geert as well..

A couple of other things to think of:

  • If you create a user in AD with account name root, you can logon as root with its AD password.
  • If you don't want AD authentication for root, you can edit /etc/pam.d/system-auth. On the line that starts with auth and also includes pam_krb5.so, add this to the end: minimum_uid=1. Authentication for root (uid=0) will now be done locally only.

Now of course ssh login is disabled for root. But when trying to login I saw in the logs /var/log/secure that root was trying to authenticate against the domain.

Feb 17 10:32:08 esx2 sshd[5838]: pam_krb5[5838]: authentication fails for 'root' (root@MAISHK.LOCAL): User not known to the underlying authentication module (Clients credentials have been revoked)

(the root account exists in the domain, but is disabled)

So I wanted to add the solution as published above.

These are the contents of the /etc/pam.d/system-auth file

#%PAM-1.0

account      required pam_per_user.so   /etc/pam.d/login.map
auth         required pam_per_user.so   /etc/pam.d/login.map
password     required pam_per_user.so   /etc/pam.d/login.map
session      required pam_per_user.so   /etc/pam.d/login.map

As you can see, no auth sufficient or /lib/security/$ISA/pam_krb5.so in the file…

Hmmmmm….

So I gather that this has changed for ESX 4.0, session pointed to /etc/pam.d/login.map

These are the contents of the /etc/pam.d/login.map file

vpxuser  : system-auth-local
*        : system-auth-generic

OK. so all users except vpxuser are pointed to /etc/pam.d/system-auth-generic

These are the contents of the /etc/pam.d/system-auth-generic file

#%PAM-1.0
# Autogenerated by esxcfg-auth

account         sufficient      /lib/security/$ISA/pam_krb5.so
account         required        pam_unix.so

auth            required        pam_env.so
auth            sufficient      pam_unix.so         try_first_pass nullok
auth            sufficient      /lib/security/$ISA/pam_krb5.so              use_first_pass
auth            required        pam_deny.so

password        required        /lib/security/$ISA/pam_passwdqc.so          min=8,8,8,7,6 similar=deny match=0
password        sufficient      pam_unix.so         try_first_pass use_authtok nullok shadow md5
password        sufficient      /lib/security/$ISA/pam_krb5.so              use_authtok
password        required        pam_deny.so

session         optional        pam_keyinit.so              revoke
session         required        pam_limits.so
session         sufficient      /lib/security/$ISA/pam_krb5.so
session         [success=1 default=ignore]      pam_succeed_if.so           service in crond quiet use_uid
session         required        pam_unix.so

Yep! There it is!

So added the minimum_uid=1 to the file

auth            sufficient      /lib/security/$ISA/pam_krb5.so       use_first_pass minimum_uid=1

Feb 17 10:58:51 ilesx2 sshd[11906]: pam_unix(system-auth-generic:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=msaidelk-server.xxx.xxxx.com  user=root

And now I see in the log when logging in as root the authentication is
pam_unix(system-auth-generic:auth)
and not pam_krb5

My Active Directory Authentication process is complete!!

Update:
Thanks to Armin van Lieshout for pointing this out to me. you can do this all with the command line as well    esxcfg-auth --enforce-local-auth=root

This will force local authentication for the defined user

2009-12-20

Updating a User attribute in the Enterprise

I was asked to update an attribute of the EmployeeNumber for each and every user in the Enterprise for a new Application that will be using the newly populated attribute for a Global Database application.

I had several examples that I could use for the job utilizing VbScript – but I wanted to use Powershell for the task.

It turned out to be a relatively easy task – using the Quest Active Directory Commandlets.

   1: add-PSSnapin quest.activeroles.admanagement 
   2:  
   3: Connect-QADService -Service domain.com -Credential (Get-Credential)
   4:  
   5: $infile = Import-Csv "c:\temp\file.csv"
   6:  
   7: $logfile = "c:\temp\logfile.log"
   8: foreach ($line in $infile) {
   9:         set-QADObject ($line.domain +"\" + $line.login) -ObjectAttributes `
  10:             @{employeeNumber=$line.guid} 
  11:         if ($? -eq $true){
  12:         Write-output "Updated: $($line.domain)\$($line.login) with employeeNumber: `
  13:             $($line.guid)" >>  $logfile
  14:         } else {
  15:         Write-output "Error in updating: $($line.domain)\$($line.login)" >> $logfile
  16:         } 
  17:     }    
  18:  
  19: ##Get Results
  20: $results = foreach ($line in $infile) {
  21:     get-QADObject ($line.domain +"\" + $line.login) -IncludedProperties ` 
  22:         Name, employeeNumber | select Name, employeeNumber 
  23:     } 
  24: $results >> $logfile
  25:  
  26: Disconnect-QADService -Service domain.com


A Quick explanation:

Line 1: Add the Quest Snapin

Line 3: Connect to the domain with acquired credentials

Lines 5-7: import the CSV file that was formatted - domain,login,guid, and create a log file for results

Lines 8-17: Go through each line in the CSV – if successful log to the file and if not then report the error to the log file.

Lines 20-24: Go through the list of users again – retrieving only the Name and EmployeeNumber properties and pipe the results in the same log file.

The script to a longer to write than it did to run.

Hope you enjoyed the ride.

2008-12-17

Time to change the Passwords again...

Do you all know how one of the biggest headaches you have is changing all the service accounts and administrative passwords on a regular basis? Well I did that this week.

This entailed changing passwords on almost 10 different accounts, local administrator passwords on over 100 servers, Local services, and tasks running under these accounts.

It wasn't so bad though the only real headache is the changing of the local passwords on the servers, the services and the tasks.

Here is how I changed the service credentials (rename the file extensions to .ps1)

changeservicecreds.txt

Change Admin Password on remote computers

changeadminpasswd.txt

Tasks - I have not found a decent script yet to perform this - when I do I will let you all know.

And of course dont forget to run Eventcombt to check that you have not missed anywhere (or naturally there are places that you never knew about in the first place :) ) to catch all those incorrect loin attempts.

Have a good one - it is about time I went to sleep..

2008-12-09

Active Directory Health Check

Well I have spent the past two days with a Microsoft PFE (Premier Field Engineer) who has been doing a quick health check for issues in our domain.

This does not replace an Active Directory Risk Assessment Process (ADRAP) - but was a highly informative and educating session.

ADRAP Objectives
  • Perform a detailed analysis of an organization‘s Active Directory environment.
  • Review Active Directory configuration.
  • Improve availability by eliminating single points of failure and by verifying that fault tolerant designs are in place.
  • Improve Active Directory performance.
  • Reduce service outages and subsequent downtime by identifying current or imminent issues.
  • Impart knowledge and skills to administer, manage, and troubleshoot Active Directory.
  • Provide tools and methodologies that will enable customers to identify existing problems.
So I have spent the past two days deep-diving into my forest.
It was a fun two days, tons of stuff I have learned, and points taken for fixing and improvement. It is always a pleasure to work with such knowledgeable people - and our PFE is highly qualified and skilled.