MSEndpointMgr

Prompt for OU location during OSD with PowerShell

I read a post on the TechNet forums the other day where a member asked for help regarding to choose the location of where the computer object would be created in Active Directory depending on region and computer system (you’ll find the thread here). I figured that I would help out and re-use part of the code that I wrote for how to prompt for the computer name during OSD.

Overview

  • Download the script
  • Create the script package
  • Update your boot image to support PowerShell
  • Implement the script in a Task Sequence

Download the script

Save the script below and call it Set-OULocationPrompt.ps1, or something familiar, and put it in your Content Library. In my lab environment I’ve saved it at the following location:
\\CAS01.contoso.com\Source$\Pkgs\OSDOULocation
The script accepts a number of parameters that it needs to function properly (they’re mandatory). First off we have the two parameters that controls the text of the Radio Buttons. These two are named RBOptionFirst and RBOptionSecond. What you enter here will also be added to the final LDAP string that will be populated in the OSDDomainOUName variable, which essentially will be where the computer object is stored in Active Directory. Secondly, we also need to specify the DomainName (NetBIOS name of your domain) and DomainSuffix (domain suffix, e.g. com or local). The last parameter called LocationList should be specified as a string array, e.g @(“Stockholm”,”Sumpan”,”Bromma”). The locations entered in here, will be populated into the drop down box, making it possible to choose any of them.
Here’s a screenshot from how it looks when I’m running this script inside a task sequence environment:
98_3
As shown in the picture, you can see what parameters I’ve fed the script with, and how it will construct the LDAP string. This popup where it shows the LDAP string is not part of the script, it’s just something extra I added for you to see how it would look like.

param(

[parameter(Mandatory=$true)]

[string]$RBOptionFirst,

[parameter(Mandatory=$true)]

[string]$RBOptionSecond,

[parameter(Mandatory=$true)]

[string]$DomainName,

[parameter(Mandatory=$true)]

[string]$DomainSuffix,

[parameter(Mandatory=$true)]

[string[]]$LocationList ) function Load-Form { $Form.Controls.AddRange(@($RBOption1, $RBOption2, $ComboBox, $Button, $GBSystem, $GBLocation)) $ComboBox.Items.AddRange($LocationList) $Form.Add_Shown({$Form.Activate()}) [void]$Form.ShowDialog() } function Set-OULocation { param(

[parameter(Mandatory=$true)]

$Location ) if ($RBOption1.Checked -eq $true) { $OULocation = “LDAP://OU=$($RBOptionFirst),OU=$($Location),DC=$($DomainName),DC=$($DomainSuffix)” } if ($RBOption2.Checked -eq $true) { $OULocation = “LDAP://OU=$($RBOptionSecond),OU=$($Location),DC=$($DomainName),DC=$($DomainSuffix)” } $TSEnvironment = New-Object -COMObject Microsoft.SMS.TSEnvironment $TSEnvironment.Value(“OSDDomainOUName”) = “$($OULocation)” $Form.Close() } # Assemblies [void][System.Reflection.Assembly]::LoadWithPartialName(“System.Drawing”) [void][System.Reflection.Assembly]::LoadWithPartialName(“System.Windows.Forms”) # Form $Form = New-Object System.Windows.Forms.Form $Form.Size = New-Object System.Drawing.Size(260,220) $Form.MinimumSize = New-Object System.Drawing.Size(260,220) $Form.MaximumSize = New-Object System.Drawing.Size(260,220) $Form.SizeGripStyle = “Hide” $Form.StartPosition = “CenterScreen” $Form.Icon = [System.Drawing.Icon]::ExtractAssociatedIcon($PSHome + “\powershell.exe”) $Form.Text = “Choose a location” $Form.ControlBox = $false $Form.TopMost = $true # Group boxes $GBSystem = New-Object System.Windows.Forms.GroupBox $GBSystem.Location = New-Object System.Drawing.Size(10,10) $GBSystem.Size = New-Object System.Drawing.Size(220,60) $GBSystem.Text = “Select system” $GBLocation = New-Object System.Windows.Forms.GroupBox $GBLocation.Location = New-Object System.Drawing.Size(10,80) $GBLocation.Size = New-Object System.Drawing.Size(220,60) $GBLocation.Text = “Select location” # Radio buttons $RBOption1 = New-Object System.Windows.Forms.RadioButton $RBOption1.Location = New-Object System.Drawing.Size(20,33) $RBOption1.Size = New-Object System.Drawing.Size(100,20) $RBOption1.Text = “$($RBOptionFirst)” $RBOption1.Add_MouseClick({$ComboBox.Enabled = $true}) $RBOption2 = New-Object System.Windows.Forms.RadioButton $RBOption2.Location = New-Object System.Drawing.Size(120,33) $RBOption2.Size = New-Object System.Drawing.Size(100,20) $RBOption2.Text = “$($RBOptionSecond)” $RBOption2.Add_MouseClick({$ComboBox.Enabled = $true}) # Combo Boxes $ComboBox = New-Object System.Windows.Forms.ComboBox $ComboBox.Location = New-Object System.Drawing.Size(20,105) $ComboBox.Size = New-Object System.Drawing.Size(200,30) $ComboBox.DropDownStyle = “DropDownList” $ComboBox.Add_SelectedValueChanged({$Button.Enabled = $true}) $ComboBox.Enabled = $false # Buttons $Button = New-Object System.Windows.Forms.Button $Button.Location = New-Object System.Drawing.Size(140,145) $Button.Size = New-Object System.Drawing.Size(80,25) $Button.Text = “OK” $Button.Enabled = $false $Button.Add_Click({Set-OULocation -Location $ComboBox.SelectedItem.ToString()}) # Load Form Load-Form

Create the script package

In order for the PowerShell script to be visible during a Task Sequence, we need to launch it with the help of a file called serviceUI.exe. That binary is available with MDT 2013 (you’d need to install MDT first, it’s also available in previous version of MDT). The file is located in these locations, depending on the architecture:

C:\Program Files\Microsoft Deployment Toolkit\Templates\Distribution\Tools\x64
C:\Program Files\Microsoft Deployment Toolkit\Templates\Distribution\Tools\x86

Depending on your boot image architecture, be sure to grab the correct version of serviceUI.exe (a x64 boot image only works with the x64 version of serviceUI.exe). Copy the serviceUI.exe to the same folder you stored the Set-OULocationPrompt.ps1 file (in my case \\CAS01.contoso.com\Source$\Pkgs\OSDOULocation).

98_1

Create a package in ConfigMgr and call it Prompt for OU Location (or something else). The package does not need to have any program, but specify the content source folder where you stored serviceUI.exe and Set-OULocationPrompt.ps1. Remember to distribute your package.

Update your boot image to support PowerShell

If you havn’t already updated your boot images with PowerShell support, follow these instructions.
1. Right-click on your boot image and select Properties.
2. Select the Optional Components tab.
3. Click on the yellow star and select the following components:

  • Microsoft .NET (WinPE-NetFx4)
  • Windows PowerShell (WinPE-PowerShell3)

Note! In ConfigMgr 2012 R2 the names of the optional components differ a bit. Add the following:

  • Microsoft .NET (WinPE-NetFx)
  • Windows PowerShell (WinPE-PowerShell)

4. Click OK and then OK again. Let the wizard update your Distribution Points.

Implement the script in a Task Sequence

1. Edit the Task Sequence that you wish to add this functionality to.
2. Add a Run Command Line step in between the Apply Windows Settings and Apply Network Settings steps.
3. Rename the Run Command Line step to Prompt for OU Location.
4. Edit the Command Line so that it looks like this:

ServiceUI.exe -process:TSProgressUI.exe %SYSTEMROOT%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -File Set-OULocationPrompt.ps1 -RBOptionFirst Workstation -RBOptionSecond Server -DomainName Contoso -DomainSuffix com -LocationList @("Stockholm","Sumpan")

5. Put a check mark in the Package box, click Browse and select your newly created package (Prompt for OU Location).
6. It’s important that the Domain OU field in the Apply Network Settings step is empty.

98_4
7. Start off a deployment of a new client. At the stage where it’s gonna execute the script, you’ll be presented with the following window:

98_0
I understand that this may not suite every environment, because the OU layout differs from environment to environment. But at least you’ve been given the tools to modify it to work in your environment.

Nickolaj Andersen

Chief Technical Architect and Enterprise Mobility MVP since 2016. Nickolaj has been in the IT industry for the past 10 years specializing in Enterprise Mobility and Security, Windows devices and deployments including automation. Awarded as PowerShell Hero in 2015 by the community for his script and tools contributions. Creator of ConfigMgr Prerequisites Tool, ConfigMgr OSD FrontEnd, ConfigMgr WebService to name a few. Frequent speaker at conferences such as Microsoft Ignite, NIC Conference and IT/Dev Connections including nordic user groups.

28 comments

  • This is great…. Do you have one or know a simple way to change this to prompt for IP Address, Gateway, DNS Servers ? Looking for this for a static environment, when they first launch the build from Boot Disk.

  • hi Nickolaj,i know this is an old thread,do you have an example of that script maybe whohc you created for eden?

  • Hi Nikolaj, i am stumbled across your post from the past and was seeking the same answer that Eden was looking for, were you able to post up the script that you did.What you created was awesome.
    I also have only one site code, and was wanting to offer up in location fields as the different OU’s, which are stacked 3-4-5 levels deep. so OSD colllection varible will get computername and this script will allow me to join the machine to the domain but select the end OU.

  • Hi All,
    I am new to SCCM and Powers hell, can i know on which basis/source of power shell command it is allowing to publish a input window. I have a power shell script when I run the script it will prompt for,
    1. Computer name
    2. User Name
    3. Password
    when i use the same script via Task sequence it is not prompting for the same, please help me on this.

  • I know this is a bit old but I’ve been looking for a way to ditch MDTs bloat so this might just fit the bill. Is there a way that my techs could run the task sequence and be prompted for their domain credentials to add a computer to an OU?

  • Hello,
    I am using the script in SCCM Current Branch (1610).
    The TS show action “Running powershell script”, but no form show, and the TS never progresses from that. No errors to be found in the smsts log
    The script works fine when running in a Win 10 Powershell.
    Can you help?

    • Please forget my stupid question.
      I normally change 2012 “run command line” instructions to “run powershell script” in SCCM 2016, but of course that’s not possible when running the script via serviceUI.
      Thanks for a great script, that I have succesfully (somewhat at least :-)) extended with computername, and different content of combobox, depending on the chosen radiobutton.
      Rgs
      Kenneth

  • I apologize I am pretty new with PowerShell and so these functions and stuff are really confusing me. Could you please put more screen shots on how I am supposed to actually configure the script for multiple OU’s? Where am I supposed to change these paramters? Where do I put what I want the text to say?
    This isn’t explained very well…..

  • Hi There, I have the same issue as client, the locations just displays next to each other in the drop down list, any ideas?

  • Hi there,
    Thanks for this article. However I am having trouble in that the locations list won’t expand each array item when running it in the TS, for example it just displays @Sydney,Melbourne,Brisbane,Perth on one line however it works when just running it on my computer in the Powershell window.
    Any ideas?
    Thanks,
    Rhys

    • I have the same problem and foud out that the problem is caused because the script is running from a dos-prompt first. But i can’t solve it.

    • I also have this same problem. It displays @location1,location2,location3,location4 as a single choice in the dropdown box. Has anyone found a solution to this?

    • Has anyone found a solution to this issue yet? The script would be incredibly useful, but I can’t get the different drop-down items to appears on separate lines 🙁

      • I found a workaround for the issue everyone’s describing here. It results in a slightly less dynamic script, so if there are changes to the locationlist it would require editing the script itself. But it works in the environment I’m using.
        I edited the function Load-Form {} section like so:
        I changed the line:
        $ComboBox.Items.AddRange($LocationList)
        To:
        $ComboBox.Items.AddRange((“loc1″,”loc2″,”loc3″,”loc4”) # $LocationList
        )
        I prefer to comment out instead of deleting so that I still have a reference for what I was doing.
        That makes it use some static values instead of having them supplied through the command line. But it does make it a proper drop-down list and it does pass the variables through to the TS, and that’s what counts in the end. 🙂
        I made some other alterations as well, removing the radio buttons, adding a textbox, coding it so that it takes the location code and pre-fills it into the textbox for a technician to finish entering the rest of the computer name.

  • Thanks for the post, this will make my deployments easier as my helpdesk techs are too lazy to put the computer in the proper OU. I am trying to implement the script as you described, using SCCM 2012 R2 and I am receiving the following error:
    powershell.exe – Application Error
    The exception unknown software exception (0xe0434352) occurred in the application at location 0xe6fb8384.
    I made some modifications to the powershell script to reflect my OU/Domain structure and it runs fine on my machine, but when I deploy it through a task sequence I get the error. Do you have any ideas or thoughts as to what could be wrong?

    • Hi Ryan,
      That doesn’t sound right, tough call though what could be the problem. Have you embedded .NET Framework and PowerShell in the boot image? Did you get that error from the smsts.log file? If not, could you please examine it more in detail and post the snippet containing the errors.
      Regards,
      Nickolaj

  • Hi Nickolaj.
    Another option would be, hardcode all the OU Departments like I did for two LDAP below: (But I dont know how to add more departments on that “if” loop. Sounds simple, but I dont know.
    function Set-OULocation {
    param(
    [parameter(Mandatory=$true)]
    $Location
    )
    if ($RBOption1.Checked -eq $true) {
    $OULocation = “LDAP://OU=Workstations,OU=IT,OU=Computers,OU=MTL,OU=LOCATIONS,DC=contoso,DC=local”
    }
    if ($RBOption2.Checked -eq $true) {
    $OULocation = “LDAP://OU=Workstations,OU=HR,OU=Computers,OU=MTL,OU=LOCATIONS,DC=contoso,DC=local”
    }
    $TSEnvironment = New-Object -COMObject Microsoft.SMS.TSEnvironment
    $TSEnvironment.Value(“OSDDomainOUName”) = “$($OULocation)”
    $Form.Close()
    Take care and thank you in advance.
    Eden

    • Hi Eden,
      Thank you very much, I hope you got a good start of 2015 as well.
      From what I can understand, it doesn’t seem to me that you need to be able to choose between a “server” or a “workstation”. Basically what you want initially is the option to have a drop down list with all of the locations in your company. If you’re to incorporate the Site Code part to the mix, you could replace the two radio buttons with another drop down list where you select the site code.
      Would you like me to create such a script for you? If so, send me an email (you’ll find my email on the About page).
      Regards,
      Nickolaj

      • Good morning Nickolaj, that is very nice from you doing that for me. That’s exactly what I was thinking about.
        I wil be deploying only workstations, but my environment is full of OUs (For Sites and Depts).
        Ill be sending you and email today.
        Thanks a lot again for your support.
        Eden

      • hi Nickolaj,i know this is an old thread,do you have an example of that script maybe whohc you created for eden?

      • Nickolaj, to save reinventing the wheel I was wondering if I could have a copy of what you were talking about with the dropdown list that references the various locations as opposed to the workstation parameter.

  • Hi Nickolaj, First, thank you for one more important tip for all of us, SCCM Admins.
    You have already mentioned at the end of your post that the script has to be changed in order to meet other OU structures, that is my case.
    I’m not a very good scripting guy, however I believe it will be easy to adapt your solution to meet my needs.
    For example, I have four levels deeper on my LDAP path, for instance (OU=Workstations,OU=%DEPARTMENT%,OU=Users-Computers,OU=%SITECODE%,OU=LOCATIONS,DC=contoso,DC=com).
    How I should Adapt your script to meet those four levels down before the Domain name?
    Thank you very much for your help in advance.

    • Hi Eden,
      First of, thank you! Regarding your question about changing the script to meet your needs, I’d need to know what you’d like to make “selectable”. With that I mean, what is is that you’d like to be prompted about to choose? Is it only by department or also site code?
      Regards,
      Nickolaj

      • Hi Nickolaj.
        For the moment, I dont need site code, however I will in the future test (Like BRA, USA, CHI, UK, RUS, SWD). Since for the moment I will deploy only to my Country (Canada), I was thinking about changing the dropdown list (Once I select workstation radio button, it will show me what Departments I have available with a workstation OU). The dropdown would show IT, HR, Accounting, per line.
        I believe I would have to change the “if” part, Im not good at powershell.
        Thank you again for being available to answer my questions.
        Have an amazing year!
        Eden

Sponsors