Tuesday, August 27, 2013

MDX sources

Dear reader, since my last posts i informed you about MDX and its workings.
in this post i proudly present the MDX sources.
In the link at the bottom of this post an .MSI can be found that will install MDX on a system. the .MSI will install the MDX script, the readme and the manual
The installation has been tested on Windows Server 2003 and Server 2008 R2. here is the readme:

Welcome to MDX
This application is written in PowerShell, to successfully start it you need to have powershell (version 2.0 and up) installed on the machine you're installing to
At first launch your settings will not reflect the settings of your deployment environment. please take your time to set the settings of MDX. refer to the manual for detailed information and usage of MDX and its settings.
On PowerShell 2.0 some parts of MDX will not work; for instance the MDT Settings Extra Apps will not show when using PowerShell 2.0.
To get things started PowerShell needs to have its execution policy set to remotesigned or lower because this script is NOT signed. please refer to http://technet.microsoft.com/en-us/library/ee176961.aspx for more information about PowerShell signing
MDX will be installed to C:\Program Files\MDX by default, feel free to change that is you want to but always check its working after this.
MDX works with a few tools locally to get fully started. in the installation MSI some of these files are incorporated, they will be installed to its default locations. the extra files are:
    - MDXIcoon1.jpg
    - Manual MDX.docx
    - Readme.txt
PsExec from the PStools must be installed on the system, preferably on a path location from your SET.
link: http://technet.microsoft.com/en-us/sysinternals/bb896649.aspx

The MDTDB from Michael Niehaus also is a MUST, the installation points to the C:\Windows\System32\WindowsPowerShell\v1.0\Modules\MDTDB directory so you can best copy the module to that path.here is the link to Michaels blog:
http://blogs.technet.com/b/mniehaus/archive/2009/05/15/manipulating-the-microsoft-deployment-toolkit-database-using-powershell.aspx
MDX’s registry entries are set in the installation of the MSI, they can be changed in the settings tab of MDX.
MDX will connect to machines through WMI, for this mechanism to work in Windows Firewall enabled machines the following rule must be enabled in the network location profile
   
    - Windows Management Instrumentation (DCOM-In)
    - Windows Management Instrumentation (WMI-In)

Also MDX will try to ping machines; for this to work the following rule must be enabled on firewalled machines:
    - File and Printer Sharing (Echo Request - ICMPv4-In) (when using IPv4 traffic
    - File and Printer Sharing (Echo Request - ICMPv6-In) (when using IPv6 traffic

Last but not least: for the remote starting via PSExec the - Remote Desktop - User-In must be opened.
PsExec itself will require a litetouch user account that has to me member of the AD group "Remote Desktop Users"
For Wake on LAN to work the used Network segments must not prohibit WOL broadcasts. please do keep in mind WOL broadcasts cannot traverse Routers, so one MDT server can only service as much network segments it is connected to.
PXE control will only work under specific conditions. please refer to link: http://www.ithastobecool.com/2009/08/17/zerotouch-for-mdt-2010-without-sccm/
to get a clear understanding of this subject.
Happy deploy-ing
Bas Huygen
negyuh@xs4all.nl

I hereby would like to thank the following technical documents and its writers:
Furthermore i would like to thank the following Colleagues for support and testing:
  • Barry Mes
  • Ylber Tahiri

Download the MDX installers here:
  - x86: https://skydrive.live.com/redir?resid=12B72EEE2C1F9871!2587
   -x64: https://skydrive.live.com/redir?resid=12B72EEE2C1F9871!2588
Please note! this installer nor the PowerShell script has been signed; Smart screen filters will warn you about that fact! 
I am still working on a valid certificate…
The MDX manual can also be downloaded separately: https://skydrive.live.com/redir?resid=12B72EEE2C1F9871!2589
I fully understand that this is the first version, feel free to download this installer and use it, when you will find a bug or think MDX should definitely use a new feature; feel free to contact me at:
mdx@xs4all.nl
Happy deploying and till next time.



Saturday, August 24, 2013

MDX technical design

Hi folks, as promised i present the next part of my MDX posts. This time i will elaborate on the technical part of MDX as well as give you, the reader, a view of how  OS deployments are done; the MDX way.

MDX design; technical facts

MDX is build in PowerShell, the GUI is designed in SAPIEN’s Primal Forms Community Edition and the application is programmed in Microsoft’s own PowerShell ISA. the script counts around 3000 lines of code of which roughly 2000 lines are accounted for by the GUI. the script is divided in 15 Functions and 6 sections.

The general idea of the applications is: unification and simplification of MDT and accompanying tools to an end-to-end deployment solution.

mdx opbouw

Architecture

MDX is designed around the functionality of a few components:

Here is the graphical representation of the design

Architecture MDX

MDX has a few sections that do the work. each section does a part of the total solution; for example there is a section in MDX that accepts input from the GUI checks its validity and, if verified, adds or modifies a corresponding computer item in MDT- in its database. another section does communicate with PzExec.exe and adds the needed variables to the tools to get a deployment started.

How does MDT accomplish end-to-end automated deployment?

The ‘secret’ of MDX is the way all under laying components are ‘orchestrated’ to make a ‘deployment symphony’ …. the way MDX does this is as follows:

  • MDX controls the MDT database (which is crucial for end-to-end automated deployments) via PowerShell
  • MDX takes variables from the UI and combines it with preconfigured components in MDT and other used tools
  • MDX manipulates a computer object from the MDT database in such a way that it is deployment ready
  • MDX adds ‘non standard’ items or features to the preconfigured building blocks like: for example: add a few applications to the deployment of a certain computer and adds a user account as local administrator to the same deployment as well
  • MDX controls the WDS PXE server and thus controls who may- and may not boot to PXE and do a deployment via the network
  • MDX can directly fire a preconfigured computer to do a deployment.

What is to be expected from doing deployments with MDX

Apart from the fact that MDX takes away the direct interaction with MDT, MDX will give the User direct control over all building blocks of the deployment chain from a single GUI. the user can start off with a computer name, check the settings and modify them and fire of the deployment to the machine.

One important thing to realize is: MDX will help the user to select ALL settings and set them without the possibility of human error (like typing). MDX eases these tasks by presenting a simple but effective UI that will help de user select those things needed MUCH faster AND easier than when he- or she would do manually in MDT itself. as a bonus it eases the management of tools like WDS or the start of MDT deployment in the traditional way.

The next post will present a real world example of deployment with MDX. till next time.

Thursday, August 22, 2013

Introducing MDX

The last weeks is have not published anything since i was working on an IT solution i am introducing here on this page.
The next posts i will elaborate and present the code of my application, this is part 1: the introduction:
MDX stands for MDT Deployment eXerience. and it is a solution targeted at Microsoft OS deployment with MDT. So you can ask me; what does it do and, even more important, what does it add to MDT since that is quite a mature OSD solution in itself. my answer will be: MDT indeed is a very great OSD solution but it has its drawbacks. let me mention a few of them:
  • The interface of MDT is quite cumbersome in respect to manipulating individual computer deployments.
  • MDT does not have any functionality to automatically start a deployment on a client
  • MDT needs ‘start-up media’ to get a deployment running like a CD or USB stick, although MDT can deliver a distribution via the network, it does not have any mechanism to control PXE servers
Because of these (and many more) drawbacks i decided to develop my own ‘shell’ around MDT and address these items.

So what does MDX do?

since i always think images speak louder then words I'll show you the interface.

As you can see the Application has its own GUI, in it there are a few input sections-, output sections and some buttons to get the whole thing running. MDX was built in PowerShell, the code for the GUI was generated by SAPIEN’s Primal Forms Community edition
MDX can do the following:
  • On input of a computer name it will try to fetch a MAC address of the particular machine, if found it will use it to add- or find this machine in MDT and attach OSD properties to it to get it deployed
  • MDX will show Computer information when the machine is online; this can be quite handy when you are to be migrating existing computers from say Windows XP to Windows 7 or 8
  • MDX has a direct link with Microsoft's WDS servers, with this link it can control PXE boots of WDS clients
  • MDX can wake a machine with Wake On LAN with one push on a button
  • MDX can start a deployment remotely with the use of PS Exec.exe (a fine piece of toolkit developed by Mark Russinovich), with this it can completely automate MDT deployments to clients.
  • MDX can add extra applications to a individual OS deployment- as well ass add an account to the local administrators group.
Al together i think it will add some nice features to MDT or as a colleague remarked “this is real automation with budget (freeware) tools!”
Next post i will elaborate on the technical workings of MDX, if all goes well i will present a download link to the source code.
till next time.

Thursday, July 11, 2013

Microsoft Failover Cluster event 1196, standard fixes do not work

Working at a client of mine we ran into an error 1196 Source Microsoft-Windows-Failover-clustering. this error indicates:

Cluster network name resource 'Cluster Name' failed registration of one or more associated DNS name(s) for the following reason:

The handle is invalid.
.
Ensure that the network adapters associated with dependent IP address resources are configured with at least one accessible DNS server.

There are many posts on the internet addressing this problem but none of them worked for us. take a look at them if you want:

  1. http://smtp25.blogspot.nl/2008/10/cluster-network-name-resource-name_23.html
  2. http://blog.subvertallmedia.com/2012/12/06/repairing-a-failover-cluster-in-windows-server-2012-live-migration-fails-dns-cluster-name-errors/
  3. http://haythamalex.wordpress.com/2012/10/02/cluster-name-failed-registration-of-one-or-more-associated-dns-names-for-the-following-reason/
  4. http://jaminquimby.com/joomla253/9-uncategorised/473-cluster-name-resource-failed-registeration-in-dns
We used the suggestions of these post and found out they are not sufficient for us; what is the matter?
All posts point to DNS registration, all fixes do not really touch DNS records.

I our case the DNS record in DNS (the CNO (Cluster Name Object)) A-record turned out to be faulty. when we removed the record we cleaned up our AD-integrated DNS records like this:

  1. removed A record from the DNS server on which the cluster nodes try to register themselves
  2. Update Server Data Files
  3. Clear Cache
  4. Restart DNS service
  5. Do this on all DNS servers in your domain or wait for the DNS replication to distribute these changes
Now we fixed the Cluster with the following recipe:
  1. Temporarily move the CNO account into the Computers container
  2. Log into one of the cluster nodes with a domain account that has the ResetPassword right in the domain
  3. Simulate failures for the cluster Network Name resource until it is in a permanent failed state
  4. Once the resource is in a Failed state, right-click on the resource, choose More Actions and then click Repair
Once this was done the A-record was created on the primary DNS server the cluster nodes point to. (this time with the right object rights)

till next time.

Important information on Error 1196: Microsoft has provided a Hotfix alailable for download here:
http://support.microsoft.com/kb/2838043
 
 

Help, my virtual DC has got virtual time!

Time services are very important in an Active Directory environment, this is because some required security mechanisms in AD do heavily rely on the correct time of a client; especially Kerberos. this service is responsible for proper authentication in a domain and Kerberos by default does not trust client tickets with a client time delta greater then 5 minutes.

To get an understanding about the Windows Time services please do read http://tigermatt.wordpress.com/2009/08/01/windows-time-for-active-directory/
The key to understanding time services in an Active Directory is: there is only ONE reliable time authority in the directory, this is the Domain Controller which holds the PDC FSMO role (the domain controller that emulates a Windows NT PDC). all other machines do synchronize their time to this PDC emulator. generally as a client you do not have to worry about your local windows time and possible skew to the PDC emulator.

So what's the purpose of this post then?

Look at this picture:
you can imagine, when the PDC emulator has got troubles with its own time; the entire Windows Forest has got time problems.

A computer keeps track of time in the following way: System time is measured by a system clock, which is typically implemented as a simple count of the number of ticks that have transpired since some arbitrary starting date, called the epoch :source: http://en.wikipedia.org/wiki/System_time

Now look at this:


The Host (physical machine) must divide all its processor slices between all VM's (and also reserve some slices for itself). so when your PDC emulator is a virtual machine it cannot rely on its own 'hardware' clock because it is inaccurate.
Windows will indicate problems like these with event error: ID 50, Source W32Time.



the way to tackle this problem is: use the virtualization software integration services. Hyper-V, for instance, installs Hyper-V Time Synchronization Service which will use the Host hardware clock to keep time.

So the bottom line in virtualized environments is:
  • Keep the Virtualization hosts time in sync with a reliable clock.
  • Use the integration services of the virtualization software to couple the Windows time to the hardware clock of the underlying host
  • Keep windows time services running (they are enabled by default), configure the PDC emulator to sync with the same time source the virtualization hosts use
My previous post (the one from July 10, 2013) can help identify what DC's are syncing with whom and the time skew they have.

Till next time

Wednesday, July 10, 2013

script to check synchronization of time service (NTP Offset) of the Domain Controllers in an Active Directory in a GUI

In larger Active Directory environments the synchronization of time on all domain controllers is essential for a healthy AD. AD services will run into problems if the times on domain controllers are ‘out-of-sync’ especially Kerberos (the authentication mechanism used by Windows Active Directory) is sensitive to this.

To check for the domain controllers and their delta (the deviation from their own local time entry and the time on the domain controller the machine synchronizes with) the command W32tm can be used.




The output is a bit hard to read though so i made a little script that extracts the NTP offset and its syncing DC to list it in a small GUI.

the output looks like this:



the GUI is generated with SAPIEN’s great PrimalForms Community Edition. the code is added here so you can use it for yourself. the script does not need any configuration because it uses the ActiveDirectory PowerShell module to get all domain controllers from a Directory.


















#Generated Form Function
function GenerateForm {
########################################################################
# Code Generated By: SAPIEN Technologies PrimalForms (Community Edition) v1.0.10.0
# Generated On: 9-7-2013 14:38
# Generated By: Bas Huygen
########################################################################

#region Import the Assemblies
[reflection.assembly]::loadwithpartialname("System.Drawing") | Out-Null
[reflection.assembly]::loadwithpartialname("System.Windows.Forms") | Out-Null
#endregion

#region Generated Form Objects
$form1 = New-Object System.Windows.Forms.Form
$label3 = New-Object System.Windows.Forms.Label
$tbNTskew = New-Object System.Windows.Forms.TextBox
$btnext = New-Object System.Windows.Forms.Button
$btPrevious = New-Object System.Windows.Forms.Button
$tbMaster = New-Object System.Windows.Forms.TextBox
$label2 = New-Object System.Windows.Forms.Label
$label1 = New-Object System.Windows.Forms.Label
$tbDC = New-Object System.Windows.Forms.TextBox
$InitialFormWindowState = New-Object System.Windows.Forms.FormWindowState
#endregion Generated Form Objects

#----------------------------------------------
#Generated Event Script Blocks
#----------------------------------------------
#Provide Custom Code for events specified in PrimalForms.

#the ActiveDirectory module is used to list all domain controllers into an array called $ArrayDC
Import-Module ActiveDirectory
$index=0
$ArrayDC=(Get-ADDomainController -Filter *|select name)

#Function Get-DCTime runs w32tm /monitor on the tested DC
#all subsequent sentences extract the values and list them in the textboxes
Function Get-DCTime($index){
$testit=$ArrayDC[$index].name
$tbDC.appendtext($testit)
$substr=(w32tm /monitor /computers:$testit|where{$_ -like "*NTP:*"})
$NTPvalue=$substr.substring(9,20)
$tbNTskew.appendtext($NTPvalue)
$RefID=$substr.substring(36)
$tbMaster.appendtext($RefID)}

#the previous and next buttons invoke Get-DCTime on a previous- or next indexID
$btPrevious_OnClick=
{
$tbDC.clear()
$tbNTskew.clear()
$tbMaster.clear()
$index=$index - 1
Get-DCTime $index
}


$btnext_OnClick=
{
$tbDC.clear()
$tbNTskew.clear()
$tbMaster.clear()
$index=$index + 1
Get-DCTime $index
}

$OnLoadForm_StateCorrection=
{#Correct the initial state of the form to prevent the .Net maximized form issue
    $form1.WindowState = $InitialFormWindowState
}

#----------------------------------------------
#region Generated Form Code
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 232
$System_Drawing_Size.Width = 407
$form1.ClientSize = $System_Drawing_Size
$form1.DataBindings.DefaultDataSourceUpdateMode = 0
$form1.Name = "form1"
$form1.Text = "AD Time services checker"

$label3.DataBindings.DefaultDataSourceUpdateMode = 0

$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 41
$System_Drawing_Point.Y = 115
$label3.Location = $System_Drawing_Point
$label3.Name = "label3"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 23
$System_Drawing_Size.Width = 125
$label3.Size = $System_Drawing_Size
$label3.TabIndex = 7
$label3.Text = "NTP Offset relative to"

$form1.Controls.Add($label3)

$tbNTskew.DataBindings.DefaultDataSourceUpdateMode = 0
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 190
$System_Drawing_Point.Y = 112
$tbNTskew.Location = $System_Drawing_Point
$tbNTskew.Name = "tbNTskew"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 20
$System_Drawing_Size.Width = 177
$tbNTskew.Size = $System_Drawing_Size
$tbNTskew.TabIndex = 6

$form1.Controls.Add($tbNTskew)


$btnext.DataBindings.DefaultDataSourceUpdateMode = 0

$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 191
$System_Drawing_Point.Y = 164
$btnext.Location = $System_Drawing_Point
$btnext.Name = "btnext"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 23
$System_Drawing_Size.Width = 75
$btnext.Size = $System_Drawing_Size
$btnext.TabIndex = 5
$btnext.Text = "Next"
$btnext.UseVisualStyleBackColor = $True
$btnext.add_Click($btnext_OnClick)

$form1.Controls.Add($btnext)


$btPrevious.DataBindings.DefaultDataSourceUpdateMode = 0

$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 109
$System_Drawing_Point.Y = 164
$btPrevious.Location = $System_Drawing_Point
$btPrevious.Name = "btPrevious"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 23
$System_Drawing_Size.Width = 75
$btPrevious.Size = $System_Drawing_Size
$btPrevious.TabIndex = 4
$btPrevious.Text = "Previous"
$btPrevious.UseVisualStyleBackColor = $True
$btPrevious.add_Click($btPrevious_OnClick)

$form1.Controls.Add($btPrevious)

$tbMaster.DataBindings.DefaultDataSourceUpdateMode = 0
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 190
$System_Drawing_Point.Y = 72
$tbMaster.Location = $System_Drawing_Point
$tbMaster.Name = "tbMaster"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 20
$System_Drawing_Size.Width = 177
$tbMaster.Size = $System_Drawing_Size
$tbMaster.TabIndex = 3

$form1.Controls.Add($tbMaster)

$label2.DataBindings.DefaultDataSourceUpdateMode = 0

$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 41
$System_Drawing_Point.Y = 75
$label2.Location = $System_Drawing_Point
$label2.Name = "label2"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 23
$System_Drawing_Size.Width = 100
$label2.Size = $System_Drawing_Size
$label2.TabIndex = 2
$label2.Text = "Synchs with"
$label2.add_Click($handler_label2_Click)

$form1.Controls.Add($label2)

$label1.DataBindings.DefaultDataSourceUpdateMode = 0

$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 41
$System_Drawing_Point.Y = 37
$label1.Location = $System_Drawing_Point
$label1.Name = "label1"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 23
$System_Drawing_Size.Width = 143
$label1.Size = $System_Drawing_Size
$label1.TabIndex = 1
$label1.Text = "Domain Controller Name: "

$form1.Controls.Add($label1)

$tbDC.DataBindings.DefaultDataSourceUpdateMode = 0
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 190
$System_Drawing_Point.Y = 34
$tbDC.Location = $System_Drawing_Point
$tbDC.Name = "tbDC"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 20
$System_Drawing_Size.Width = 177
$tbDC.Size = $System_Drawing_Size
$tbDC.TabIndex = 0

$form1.Controls.Add($tbDC)

#endregion Generated Form Code

#Save the initial state of the form
$InitialFormWindowState = $form1.WindowState
#Init the OnLoad event to correct the initial state of the form
$form1.add_Load($OnLoadForm_StateCorrection)
#Show the Form
$form1.ShowDialog()| Out-Null

} #End Function

#Call the Function
GenerateForm

Monday, May 27, 2013

The trouble with single label (Active Directory) domain names

Today on a domain of a client of mine (that has a single label Active Directory domain) i experienced a strange phenomenon
a new deployed client computers could not join a domain, the machine got the message An Active Directory domain controller for this domain could not be contacted

I went through all standard troubleshooting steps like:
  • Check local connectivity of the client
    • Hardware
    • Ipconfig
    • ping to the default gateway
  • Check name resolution
    • DNS
    • WINS
Everything looked ok but how could this be? next up were the servers, went through all tests on the domain controllers and services like DNS and DHCP, i found some faults but this were minor. coming to this point I got the impression I have overlooked something; but what?
Thing is: looking at a problem like this one troubleshooting should be started from the source. checking name resolution on the client revealed one interesting thing: the machine could find a machine.domainlabel but as soon as the Windows 7 client wanted to resolve the domain it could not find it...

You see when using a single label domain you normally enter a domain like domain.local but with a single label domain name you enter domain doing this triggers a client to use NETBIOS name resolution! after checking the DHCP I found the fault. the first WINS server stated in DHCP pointed to a server on which a day earlier the WINS was uninstalled. after installing WINS and enabling Use WINS forward lookup everything worked as normal.

this calls for one conclusion: the main problem with single label domain names is that it triggers clients to use WINS name resolution is a number of cases. since all modern AD integrated software uses DNS name resolution a lot of things in these programs probably will falter.

till next time.