Category Archives: OSD / SCCM / MDT

0x8007000f Task Sequence Error

Really quick post on issue experienced recently.

We were trying to build some Lenovo T470Ps and one was exhibiting this error just before the task sequence was to start and failed as a result before we even got off the ground. The error translates to The system cannot find the drive specified. However I knew for a fact that the drivers were OK as other T470Ps were building fine.

Transpires that somewhere along the way, something had indeed got mixed up on the disk and it was having problems with the config. I initially tried a DISKPART then CLEAN but this wasn’t enough and it was continuing to fail.

In the end we resorted to doing the task sequence’s job manually and recreating the partitions as follows:

Open CMD prompt (F8):

1. Diskpart
2. Select disk 0 (0 being the disk to setup)
3. Clean
4. Convert gpt
5. Create partition efi size=300
6. Format quick fs=FAT32
7. Create partition msr size=128
8. Create partition primary
9. Assign letter=c
10.Format quick fs=NTFS

Exit DISKPART and try again – this time the task sequence continued as expected.

Change login screen language in MDT / SCCM (Server Core)

I came across an interesting (if very frustrating) issue recently when a client provided me with an updated version of Windows Server 2012 R2. Prior to being handed the new media, I was using my own copy of Server 2012 R2 which is Build 6.3.9600.16384. I set up my MDT build which had a task sequence for each version of Server 2012 R2, Standard, Standard Core, Datacenter and Datacenter Core.  Everything was fine and the UI language was configured correctly throughout.

I received the new media which was Build 6.3.9600.17415 and replaced my original copy of Server with this new version. All appeared to be fine until I tried to log in to the two Server Core versions where my password wasn’t being accepted. It transpires that these have some kind of bug / difference whereby the Input Locale doesn’t change to the configured language. In my case, I had an American (en-us) keyboard and I wanted to use an English (en-gb) keyboard. Weirdly, this was only the case for the core versions; the GUI versions were fine.

I spent a good deal of time scouring the internet for a fix to this and it appears quite a few people had the same issue, eg:
https://social.technet.microsoft.com/Forums/windowsserver/en-US/d82dd905-e346-4a94-87e6-a78d59f4941c/keyboard-layout-wrong-on-logon-screen-but-fine-on-desktop?forum=windowsserver2008r2general
or
http://windowsitpro.com/systems-management/how-do-i-configure-default-keyboard-layout-during-login

This one was also interesting but the application of the fix wasn’t explained clearly and I gave up on it.

Mostly, the ‘fix’ was to change the HKEY_CURRENT_USER\Keyboard Layout\Preload setting to the proper value and this does seem to work if you log on and change this manually in the registry. However I could not get this setting to stick when I applied it through any scripting mechanism.

I eventually found a solution though through group policy which I applied during the build. The steps below are for MDT but the same can easily be applied for SCCM.

Create a new GPO and browse to Computer Configuration\Policies\Admin Templates\System\Locale Services
Change Disallow copying of user input methods to the system account for sign in to Enabled.
Create a backup of the policy and copy it to your deployment share. Rename it from {GUID} to LogonKB. I created a custom directory to store this in called Custom2012R2. Under this I had a directory called GPOBackup which contain any GPOs I need to apply.
Download a copy of lgpo.exe and stick it in your tools\%architecture% directory (in practice you want the x64 version)
Create a TS step just before the Tattoo step called Copy GPOs Locally as below
Command line: xcopy “%DEPLOYROOT%\Custom_2012R2\GPOBackup” C:\Windows\Temp /e /i

6. Next, create another step to apply the GPO, directly after the copy step and call this Apply GPO logon keyboard.
Command line:

“%DEPLOYROOT%\Tools\%ARCHITECTURE%\lgpo.exe” /g “C:\Windows\Temp\LogonKB”

It is important these two steps are early in the task sequence as the ‘damage’ is already done if you apply them too late. What is actually happening is that the GPO you have applied is preventing the Input Locale from being copied over to the login screen keyboard locale. You can see this before and after by running up the systeminfo command from a command prompt. On a machine without the application of the GPO the Input Locale will show up as:

Input Locale: en-us;English (united States)

and this will get copied over to the login screen language during build time. The GPO prevents this from happening and keeps the setting at en-gb.

I hope this will save others many hours of frustration.

New OSD Task Sequence Not Displaying

Recently been testing an upgrade scenario from ConfigMgr 2012 SP2 to Current Branch 1702 and during the course of putting together the legacy environment I came across a strange issue I’d not seen before. Essentially it goes like this:

A new OSD task sequence is created (doesn’t matter whether it is MDT-infused or not) and is deployed to All Unknown Computers. In my case I was using boot media to reach the WinPE environment on my test VM but there were no task sequences displayed. Checking the smsts.log file in the WinPE environment, it suggests that no policies are found.

The first time this happened the task sequence eventually appeared after about an hour or so. The next day I created a new one and exactly the same thing happened, with just the old TS showing up. I then saw this thread and changed my new task sequence availability time back 1 day. Et voila, the task sequence appeared.

Hope this helps anyone else scratching their head…

OSD Scripting Hacks Part 4 – Renaming NICs

In a new series of short posts I’m going to show how to get around some frustrations I have had with the lack of GPO support for some common requirements plus a few other issues I have come across which have crept up recently.

More for a bit of fun really but this was another serious request I have had where a machine contained several adaptors, they should all be sequentially named to specification, in this case NIC1, NIC2, NIC3 ,etc.

Here’s the script. It renames the adaptor numerically and outputs to a logfile:

# Rename NICs
$number=0
ForEach($nic in (Get-NetAdapter -Name *)) {
$number += 1
Get-NetAdapter -Name $nic.Name | Rename-NetAdapter -NewName NIC$number - PassThru | Out-File %WinDir%\Temp\NicName.log -Append
 }

For MDT users I recommend using a commandline action as follows:

powershell.exe -ExecutionPolicy Bypass -command "$number=0; ForEach($nic in (Get-NetAdapter -Name *)) { $number+=1; Get-NetAdapter -Name $nic.Name | Rename-NetAdapter -NewName NIC$number -PassThru | Out-File %WinDir%\Temp\NicName.log -Append }"

That concludes this series for now until such time as another request comes my way…

 

OSD Scripting Hacks Part 3 – Disable NETBIOS in Powershell

In a new series of short posts I’m going to show how to get around some frustrations I have had with the lack of GPO support for some common requirements plus a few other issues I have come across which have crept up recently.

Another requirement that came up in my recent project was to disable the NETBIOS over TCP/IP setting function under the network adaptor settings | IPv4 properties | Advanced. The issue here is that there are multiple GUIDs present in the registry that must be changed and these can’t be easily predicted. Fortunately Powershell is kind to us and allows the use of a wildcard (*) to just hit them all. This is achieved with the following script:

 # Disables NETBIOS over TCP/IP
set-ItemProperty HKLM:\SYSTEM\CurrentControlSet\services\NetBT\Parameters\Interfaces\tcpip* -Name NetbiosOptions -Value 2

For MDT users, I recommend using a commandline action as follows:

powershell.exe -ExecutionPolicy Bypass -command "set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\services\NetBT\Parameters\Interfaces\tcpip*' -Name NetbiosOptions -Value 2"

Next, renaming NICs!

OSD Scripting Hacks Part 2 – Performance Settings

In a new series of short posts I’m going to show how to get around some frustrations I have had with the lack of GPO support for some common requirements plus a few other issues I have come across which have crept up recently.

In part 2, I will show you how to change the performance settings via a script which can be run from a task sequence step. Like the file extensions in Part 1, this was another area that (at the time of writing) seems frustratingly missing from group policy. I was creating an MDT task sequence recently to build some servers and one of the requirements was that the Visual Effects setting was specifically set for ‘Best Performance’ as opposed to Let Windows choose…

Anyway, the script:

# VisualFX - Best Performance
$RegKey ="HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VisualEffects"
Set-ItemProperty -Path $RegKey -Name VisualFXSetting -Type DWORD -Value 2

For MDT, you may wish to run this as a commandline as follows:

powershell.exe -ExecutionPolicy Bypass -command "set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VisualEffects' -Name VisualFXSetting -Type DWORD -Value 2"

In the above I set the value to 2 for best performance. Other values can be:
0 – Let Windows choose what’s best for my computer settings.
1 – for Adjust for best appearance settings.
2 – for Adjust for best Performance settings.
3 – for Custom settings.

OSD Scripting Hack Part 1 – Enable file extensions for all users

In a new series of short posts I’m going to show how to get around some frustrations I have had with the lack of GPO support for some common requirements plus a few other issues I have come across which have crept up recently.

First in the series is a build fix for file extensions. By default, these aren’t enabled and at the time of writing there isn’t a GPO that can be applied that applies them for users when they log on so they have to be enabled manually. Personally I find it frustrating that I can’t see what kind of file something is and it is usually the first thing I change when  I log into a new computer. Anyway, among others, this became a requirement for a recent project I was on and after a bit of playing around and further research I came up with the following Powershell script:

reg load HKLM\DefaultUser C:\Users\Default\NTUSER.DAT
 $path = "HKLM:\Defaultuser\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"
 New-ItemProperty -Path $path -Name HideFileExt -Value "0" -Type DWord
 reg unload HKLM\DefaultUser

This should be run as a task sequence step but depending on your deployment tool of choice, Powershell commands can occasionally be a little fussy. If you are using MDT, you might find the following works better if set up as a commandline:

Powershell.exe -ExecutionPolicy Bypass -command "reg load HKLM\DefaultUser C:\Users\Default\NTUSER.DAT; New-ItemProperty -Path 'HKLM:\Defaultuser\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced' -Name HideFileExt -Value 0 -Type DWord; reg unload HKLM\DefaultUser"

The above should also work fine for SCCM although SCCM isn’t as picky as stand-alone MDT so either might work there.

Next time, Performance settings.

Securing Web Services

One of the main criticisms of using web services is that they’re inherently insecure. By default anyone can access them and if they have functions to actually change anything then one must proceed with caution.

My current client was somewhat skeptical about their introduction and the only way I could bring them round to the wonderful gifts that they offer was to promise that we’d investigate a secure way to present them. There was some trial and error but I think we came up with a pretty good solution which I shall share here.

Why use web services at all?

There are an awful lot of reasons so I’ll keep it to why I like to use them. They’re a cheap and cheerful way to provide functionality by proxy.  They can be used to off-load many tasks which, if you don’t have the budget for something like the wonderful System Center Orchestrator product, can make a great shoe-in. OK a little more explanation…

From a deployment perspective they can provide a mechanism to access Active Directory, MDT and SCCM without a client OS necessarily being part of AD. For example, they could be called from a WinPE session to update a database or query/update an OU. They’re relatively easy to write if you possess basic programming skills but if not, then I fully recommend you check out Maik Koster’s toolset here.  Installation instructions are provided but do fall a little short on security, so let me crack on.

Securing the Web Services

First of all, if you run a PKI infrastructure, let me recommend you you change the URL to run under HTTPS. I am not going into detail in this respect here as there are plenty of how-to’s on this topic elsewhere on the web. Suffice to say it’s a no-brainer if you’re truly concerned about security, particularly if there are any services which need to pass confidential information such as passwords.

Next, ensure you have read Maik’s security blog for his web services. They’re basic but a good start. Now to secure it properly:

Securing the website via pass-through authentication

Follow these steps to lock down page to an AD group. I won’t go into detail on  clicky-clicky, I assume if you have come this far you’ll know this stuff from within IIS and from the screen shots provided. If enough people tell me otherwise, I’ll review this though.

  1. Before changing anything, this is the expected configuration:

2. Install url authorisation feature and windows authentication features from server manager or Powershell.

3. After installation, change authentication model as follows (apologies, image is a little blurry, I’ll try to update in due course).

4. Update Authorisation rules. Note that All Users verbs have been changed to POST. This prevents the web page appearing at all without a login prompt (ie the initial GET action is prevented from running) for all users other than those in that are members of the specified AD group.

 

5. Providers should remain at their defaults:

6. Update local Intranet sites. If the site isn’t trusted you may need to add this to local intranet sites to prevent a login box appearing.

 

You should now have full pass-through authentication for your web service, dependent on membership of the AD group of your choice.

SCCM Client “Currently Intranet” doesn’t change to “Currently Internet”

Environment: SCCM 1602, full HTTPS communication throughout.

I ran into this problem recently at a client where we’d installed SCCM 1602 with full HTTPS communication throughout. One of the requirements was to deploy software and software updates to clients on the internet as well as the intranet. All went pretty much according to plan until I put a laptop on the internet to test deployment of said software.  The issue I faced was that whatever I did, I couldn’t make the laptop drop to Currently Internet from Currently Intranet. Looking at the LocationServices.log confirmed my suspicions: it was trying to contact an MP on the internal network.

Attempting to refresh TRK from AD LocationServices 22/06/2016 16:27:50 3024 (0x0BD0)
Unexpected row count (0) retrieved from AD. LocationServices 22/06/2016 16:27:50 3024 (0x0BD0)
Failed to get TRK from AD LocationServices 22/06/2016 16:27:50 3024 (0x0BD0)
Failed to send request to /SMS_MP/.sms_aut?MPKEYINFORMATIONEX at host ICSKSCCMMP02.local.com, error 0x2ee2 LocationServices 22/06/2016 16:28:11 3024 (0x0BD0)
[CCMHTTP] ERROR: URL=https://ICSKSCCMMP02.local.com/SMS_MP/.sms_aut?MPKEYINFORMATIONEX, Port=443, Options=63, Code=12002, Text=ERROR_WINHTTP_TIMEOUT LocationServices 22/06/2016 16:28:11 3024 (0x0BD0)
Raising event:
instance of CCM_CcmHttp_Status
{
ClientID = “GUID:0abd2d73-79a1-4b55-91de-1bc56d93050c”;
DateTime = “20160622152811.098000+000”;
HostName = “ICSKSCCMMP02.local.com”;
HRESULT = “0x80072ee2”;
ProcessID = 2948;
StatusCode = 600;
ThreadID = 3024;
};
LocationServices 22/06/2016 16:28:11 3024 (0x0BD0)
Successfully queued event on HTTP/HTTPS failure for server ‘ICSKSCCMMP02.local.com’. LocationServices 22/06/2016 16:28:11 3024 (0x0BD0)
MP ICSKSCCMMP02 capability is not available LocationServices 22/06/2016 16:28:11 3024 (0x0BD0)
Executing Task LSRefreshDefaultMPTask LocationServices 22/06/2016 16:28:12 2136 (0x0858)
Current AD site of machine is North-West LocationServices 22/06/2016 16:28:12 6028 (0x178C)
Failed to send request to /SMS_MP/.sms_aut?MPKEYINFORMATIONEX at host ICSKSCCMMP02, error 0x2ee2 LocationServices 22/06/2016 16:28:32 3024 (0x0BD0)

 During my investigations I looked into what criteria ConfigMgr used to discover if it was on the internet and found the answer here:

When the client detects a change in network, this kicks off service location to find its intranet management point (the default management point in its assigned site or proxy management point if it’s within the boundaries of a secondary site that belongs to its assigned site).  If service location fails, the client deduces that it must be on the Internet and so tries to communicate with its assigned Internet-based management point.  The assigned Internet-based management point always directs the client to the Internet-based site systems in the site, and never to intranet-based site systems or to Internet-based site systems in another site.

So I looked at my default management point. This was also set (via an alias) as the internet management point (owing to the IP policy here they don’t really ‘do’ DMZs but that’s another story). So what was happening? Well essentially when the local network was disconnected and the computer was switched over to an internet connection, it wasn’t able to differentiate the default MP from the internet MP and hence thought it was still on the local network.

The Solution

I changed the default Management Point from the internet facing MP to a local MP that wasn’t accessible via the internet. This allowed the client to figure out that it was no longer on the local network and change over to the internet. Once this happened, it was then able to pick the correct MP and the correct DP to talk to and order was once again restored. I guess this isn’t a common scenario but something to look out for if you’re experiencing the problem described.