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.

Sign PDF Documents with the Surface Pen

In my occasional series on Microsoft Surface-related posts, I thought I’d just do a quick one on signing a document. This seems like the type of thing you’d want to use the Surface pen for, right? Well it’s probably the single most useful thing I would want to use it for anyway. The trouble is, by default at least, when you open a PDF it opens up in Edge and you are unable to use the pen to sign with…

You’ll also probably find it doesn’t seem to work in Adobe Reader and many other PDF readers. However not to worry – there is a built in reader app that can help with this very task! I feel a little stupid for only just realising this but try opening the app in Drawboard PDF and you can make adjustments with your pen to your heart’s content – and then save them. Great.

You’re probably thinking I can’t believe he only just found that out and frankly, after owning my Surface for 10 months I’m kind of thinking the same. I can only assume that I’m not the only one to realise this late in the day and hopefully I can help others see the light.

WSUS / SUP : System.Net.WebException: The request failed with HTTP status 401: unauthorized.

I noticed recently that after an extended period of being switched off, the Software Update Point in SCCM lab looked extremely poorly. I’m not sure why this was or if it had anything to do with being switched off for several days but in any case here is the scenario:

WSUS lives on a separate server to my site server and SQL is on another separate box (I know, better to install it on the same box as site server but I find few customers these days that’ll let me do this so I keep it this way to replicate their environments as far as possible). Anyway I digress; the setup is as follows:

Comms: HTTPS / SSL throughout  for SCCM and for WSUS.
Version: Current Branch 1606
OS: Server 2012 R2  (WSUS 6.2, commonly referred to as WSUS 4.0)

After noticing some errors in my component status messages with regard to WSUS, I checked the WSUSCtrl.log and saw the following message appearing every minute or so:

System.Net.WebException: The request failed with HTTP status 401: Unauthorized.~~ at Microsoft.UpdateServices.Administration.AdminProxy.CreateUpdateServer(Object[] args)~~ at Microsoft.UpdateServices.Administration.AdminProxy.GetUpdateServer()~~ at Microsoft.SystemsManagementServer.WSUS.WSUSServer.ConnectToWSUSServer(String ServerName, Boolean UseSSL, Int32 PortNumber)
Failures reported during periodic health check by the WSUS Server UT1.BC.LOCAL. Will retry check in 1 minutes

Furthermore, if I ran WSUSUtil checkhealth on the SUP, my Application Log read as follows:

The Reporting Web Service is not working.
 The API Remoting Web Service is not working.
 The Server Synchronization Web Service is not working.
 The Client Web Service is not working.
 The SimpleAuth Web Service is not working.
 The DSS Authentication Web Service is not working.
 On 13/10/2016 19:56:06, component SMS_WSUS_CONTROL_MANAGER on computer UT1.TEST.LOCAL reported: WSUS Control Manager failed to configure proxy settings on WSUS Server "UT1.TEST.LOCAL".

Possible cause: WSUS Server version 3.0 SP2 or above is not installed or cannot be contacted.
 Solution: Verify that the WSUS Server version 3.0 SP2 or greater is installed. Verify that the IIS ports configured in the site are same as those configured on the WSUS IIS website.You can receive failure because proxy is set but proxy name is not specified or proxy server port is invalid.

Not good. Fortunately the fix was straightforward:

I ran c:\Program Files\Update Services\Tools\wsusutil.exe configuressl ut1.test.local
and then I saw URL: https://ut1.test.local:8531 appear on the screen.
Then restarted the IIS services (IISAdmin, WWW) and all sprang to life. An IISReset would probably have done the same thing. After this the log should start to look like that below.

wsuslog

(Open image in a new tab to see more clearly)

Assuming you are configured for SSL and for some reason you see something like URL: http://ut1.test.local:8530 instead, then most likely the SSL settings for WSUS are probably incorrect. Ensure you have the settings below in place in IIS:

1. WSUS Administration. SSL Settings should be unchecked / ignore.
2. ApiRemoting30. SSL settings should be checked / ignore.
3. aspnet_client. SSL settings should be unchecked / ignore.
4. ClientWebService. SSL settings should be checked /ignore
5. Content. SSL settings should be unchecked / ignore.
6. DSSAuthWebService. SSL settings should be checked/ ignore.
7. Inventory. SSL settings should be unchecked / ignore.
8. ReportingWebService. SSL settings should be unchecked / ignore.
9. SelfUpdate. SSL settings should be unchecked / ignore.
10. ServerSyncWebService. SSL settings should be checked / ignore.
11. SimpleAuthWebService. SSL settings should be checked / ignore.

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.

‘The software change returned error code 0xc1800118 (-1048575720)

So you’re testing out deployment of the new 1607 feature upgrade for Windows 10 in your shiny new 1606 SCCM console. The upgrade appears in your client’s Software Center and starts downloading* and then installing…and then disaster. You are hit with the dreaded message The software change returned error code 0xC1800118(-1048575720). Some Googling reveals a lot of the same responses, ie that you’ve allegedly forgotten to apply KB3159706 before synchronising. (Just in case this happens to be the case, check out the MS blog with appropriate links) but of course you we all know you applied that correctly, so what else?

It goes without saying that if you’re up and running with the official advice then leave as is and don’t fiddle further unnecessarily. However, if you’re still reading then the chances are that that isn’t the case. Well there are a number of other solutions describing how you must add the MIME type for the WSUS server as follows:

extension: .esd   MIME Type: Application/octet-stream
or
extension: .esd   MIME Type: application/vnd.ms-cab-compressed

mimetype

Try these for sure. Ensure you restart the IIS web services after adding the entry.

Again, however, this didn’t fix my issue. Maybe I was looking in the wrong places but I could find no information on the internet which fitted my particular set of circumstances, although there appear to be many in the same boat with unanswered forum posts.

RESOLUTION

After some head-scratching I did find a solution that worked. I simply reinstalled the the SCCM client agent from the client folder on the site server. Huh? This didn’t make too much sense to me until I took a closer look at the client version number before and after.
My freshly-built Windows 10 1511 builds were installing with client version 5.00.8355.1307:

8355

After re-installation of the new client, the version number was 5.00.8412.1307:

8412

Following this I was able to make the feature upgrade run without error. Subsequent SCCM servicing upgrades also upgraded the client files in this directory and the new client version has clearly fixed some compatibility issues with the 1607 feature upgrade.

I updated the default SCCM client version in the console and ensured all new 1511 builds were running the newer client version. Sure enough, feature updates worked perfectly following every new build. I then rolled out the new client agent version to my existing estate. This will obviously be a pre-requisite to ensure all machines upgrade as expected when the 1607 feature upgrade is rolled out wholesale.

Hope these tips help someone else suffering with upgrade frustrations.

* Another issue I have seen is where the feature upgrade gets stuck downloading at 0%. I solved this problem by simply creating a new package and re-downloading the feature upgrade and re-deploying.

SCCM Current Branch – Updates and Servicing Pane Empty!

So you’re looking forward to upgrading to the next CB version of SCCM and growing frustrated at the fact there is nothing appearing in  Updates and Servicing pane. In fact, there should be several hotfixes showing in addition to the latest and greatest version of ConfigMgr. But….nothing.

NoServicing

You can be logged in as a full administrator and nothing will appear!

SOLUTION:

Open the console as the user which installed ConfigMgr in the first instance. Failing this (user has since been deleted, etc) go to Administration | Security | Administrative Users and look for a user that has All instances of the objects that are related to the assigned security roles selected. The chances are, that the user you are having problems with doesn’t have this selected (yes, even if they’re a full admin) and this is the crux of the problem. SecurityScope

Now, open the console with the user who has this permission and you should now get a message saying that there are updates available. Go to the security node and make the appropriate changes described above to the users or groups that you wish to have access to this view.

Et Voila!

SCCM Reports Prompting For Credentials

A really quick post on an issue I had the other week.
The environment was https and all appropriate certs were in place. The production environment was working perfectly but in dev, when we used the FQDN to reach the report server we kept getting prompted for credentials. After double checking everything was set up exactly as I’d set it up for prod I found the credentials kept appearing. I tested the scenario without https and there were no prompts.

RESOLUTION

I added the site to the local intranet sites in IE and the prompting went away. A GPO might be called for if you experience this in an enterprise environment.

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.