Sunday, November 5, 2017

Verify Computer Name against Active Directory in SCCM task sequence

Recently, I have been asked by one of my customers, for computer name checks against Active Directory before setting it in SCCM task sequence for new computer deployment.
Searching the web didn't came up with any results, and since the request sounded really reasonable to me, I decided to take the challenge.

My solution had to be secure. meaning, password cannot be written in clear text or any other non-secure method in any way.

After a lot of research I came up with the following steps to complete this request:

  1.  Enable PowerShell in boot images.
  2. Create a package that copy's Active Directory module files to the boot image, and run it in task sequence.
  3. Create a PowerShell script that do the following:
    • Interact with task sequence.
    • load PowerShell form for prompting computer name selection.
    • Import Active Directory module, securely connect to Active Directory and check the name against Active Directory.
    • Set computer name as OSDComputername TS variable (assuming that the name not exists).

Enable PowerShell in boot images

In order to run the PowerShell form within WinPE environment, PowerShell needs to be enabled in the boot image first.
To do that, right click the relevant boot image and go to properties.
Go to Optional Components tab and add Windows PowerShell component and additional components as well. (don't forget to update your distribution point):

 
 
  

Create Active Directory module files package

In order to connect to Active Directory and check if the computer name exist, Active Directory module needs to be imported within PowerShell.
My solution is coping Active Directory module files to the boot image before running PowerShell script step in task sequence, with a regular package.
  • From any computer with RSAT, copy the following folders:
%windir%\System32\WindowsPowerShell\v1.0\Modules\ActiveDirectory
%windir%\SysWOW64\WindowsPowerShell\v1.0\Modules\ActiveDirectory (x64-image only)
%windir%\Microsoft.NET\assembly\GAC_32\Microsoft.ActiveDirectory.Management
%windir%\Microsoft.NET\assembly\GAC_32\Microsoft.ActiveDirectory.Management.Resources
%windir%\Microsoft.NET\assembly\GAC_64\Microsoft.ActiveDirectory.Management (x64-image Only)
%windir%\Microsoft.NET\assembly\GAC_64\Microsoft.ActiveDirectory.Management.Resources (x64-image Only)
%windir%\WinSxS\amd64_microsoft.activedir..anagement.resources_31bf3856ad364e35_6.3.9431.0_en-us_fb186ae865900ae8 (x64-image Only)
%windir%\WinSxS\x86_microsoft.activedirectory.management_31bf3856ad364e35_6.3.9431.0_none_b85eb2e785c286ef
%windir%\WinSxS\msil_microsoft-windows-d..ivecenter.resources_31bf3856ad364e35_6.3.9431.0_en-us_38f21d039944539f

  • Create a simple batch script that creates the relevant folders in the boot image and copy the files to it:

md x:\windows\System32\WindowsPowerShell\v1.0\Modules\ActiveDirectory
xcopy ActiveDirectory\* x:\windows\System32\WindowsPowerShell\v1.0\Modules\ActiveDirectory /e /y

md x:\windows\Microsoft.NET\assembly\GAC_32\Microsoft.ActiveDirectory.Management
xcopy Microsoft.ActiveDirectory.Management x:\windows\Microsoft.NET\assembly\GAC_32\Microsoft.ActiveDirectory.Management /e /y

md x:\windows\Microsoft.NET\assembly\GAC_32\Microsoft.ActiveDirectory.Management.Resources
xcopy Microsoft.ActiveDirectory.Management.Resources x:\windows\Microsoft.NET\assembly\GAC_32\Microsoft.ActiveDirectory.Management.Resources /e /y

md x:\windows\WinSxS\x86_microsoft.activedirectory.management_31bf3856ad364e35_6.3.9431.0_none_b85eb2e785c286ef
xcopy x86_microsoft.activedirectory.management_31bf3856ad364e35_6.3.9431.0_none_b85eb2e785c286ef x:\windows\WinSxS\x86_microsoft.activedirectory.management_31bf3856ad364e35_6.3.9431.0_none_b85eb2e785c286ef /e /y

md x:\windows\WinSxS\msil_microsoft-windows-d..ivecenter.resources_31bf3856ad364e35_6.3.9431.0_en-us_38f21d039944539f
xcopy msil_microsoft-windows-d..ivecenter.resources_31bf3856ad364e35_6.3.9431.0_en-us_38f21d039944539f x:\windows\WinSxS\msil_microsoft-windows-d..ivecenter.resources_31bf3856ad364e35_6.3.9431.0_en-us_38f21d039944539f /e /y


I have uploaded the files with the script for x86 and x64 boot images: AD PS files
Just extract the files as is and set it as a source for the following SCCM package.

Create a regular package in SCCM without any program, and set the source files for the file you just download and extract (or created manually).



PowerShell form script

The script will do the following:
  • Place task sequence visibility in the background.
  • Load the computer name form.
  • Prompt for credentials (with get-credentials command).
  • Import Active Directory module.
  • Check against Active Directory for computer name and loop until the name cannot be found.
  • Set the computer name as OSDComputername task sequence variable.
######## Close the TS UI temporarily
$TSProgressUI = New-Object -COMObject Microsoft.SMS.TSProgressUI
$TSProgressUI.CloseProgressDialog()

function button ($title,$mailbx, $WF, $TF) {
###################Load Assembly for creating form & button######
[void][System.Reflection.Assembly]::LoadWithPartialName( “System.Windows.Forms”)
[void][System.Reflection.Assembly]::LoadWithPartialName( “Microsoft.VisualBasic”)

#####Define the form size & placement
$form = New-Object “System.Windows.Forms.Form”;
 $form.Width = 500;
 $form.Height = 150;
 $form.Text = $title;
 $form.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen;

##############Define text label1
 $textLabel1 = New-Object “System.Windows.Forms.Label”;
 $textLabel1.Left = 25;
 $textLabel1.Top = 15;

$textLabel1.Text = $mailbx;
############Define text box1 for input
 $textBox1 = New-Object “System.Windows.Forms.TextBox”;
 $textBox1.Left = 150;
 $textBox1.Top = 10;
 $textBox1.width = 200;


#############Define default values for the input boxes
$defaultValue = “”
$textBox1.Text = $defaultValue;

#############define OK button
 $button = New-Object “System.Windows.Forms.Button”;
 $button.Left = 360;
 $button.Top = 85;
 $button.Width = 100;
 $button.Text = “Ok”;

############# This is when you have to close the form after getting values
 $eventHandler = [System.EventHandler]{
 $textBox1.Text;
 $form.Close();};

$button.Add_Click($eventHandler) ;
#############Add controls to all the above objects defined
 $form.Controls.Add($button);
 $form.Controls.Add($textLabel1);
 $form.Controls.Add($textBox1);
 $ret = $form.ShowDialog();


#################return values
return $textBox1.Text
 }

$return= button “Enter Computer Name” “Computer Name”
#################Below variables will get the values that had been entered by the user
$return

#######################
#Import AD Module#
#######################
$C = Get-Credential
import-module activedirectory -force

while (get-adcomputer -filter * -credential $c -server YOUR-DC-NAME | Where-Object { $_.Name -eq ("$return") })
{$return= button “Enter Computer Name” “Computer Name Exist”  {break;}}

########## Enter OSDComputername Value To TS

   $OSDComputerName = $return
   $TSEnv = New-Object -COMObject Microsoft.SMS.TSEnvironment
   $TSEnv.Value("OSDComputerName") = "$($OSDComputerName)"
   $Form.Close()

  
 
In order to interact with the PowerShell from within the task sequence, you need to run it with a file called ServiceUI.exe from MDT.
The file located in the following path:
C:\Program Files\Microsoft Deployment Toolkit\Templates\Distribution\Tools\X-Your Architecture (be sure to run it with the correct Boot Image architecture).

Create another package (no program needed) with the following files in it:
  • ServiceUI.exe
  • PowerShell script. (can be download from here - change DC name in line 77)


Task Sequence

In your task sequence add two steps:
Place those steps right after partition disk step. this is very important, otherwise your task will fail.
  • Copy AD Module Files step:
    This would be a "Run Command Line" step and will be using the first package that was created.

  
  • Choose Computer Name step:
    This would be a "Run Command Line" step again .
    This time, we'll use the second package created to run the PowerShell Script with ServiceUI.exe.
    Command:
    serviceUI.exe -process:TSProgressUI.exe %SYSTEMROOT%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -File OSDComp.ps1
For x64 boot image, change for ServiceUIx64.exe file.
 
 
 

Task Sequence appearance

Running the task sequence with the following changes will prompt for computer name:
 
 
Ask for credentials:

 
 
Prompt for name exist until name cannot be found in Active Directory:
 
 
 



 References:
 
 
 

No comments:

Post a Comment