ConfigMgr 1906

ConfigMgr 1906 was released today, it wont show up immediately in you ConfigMgr consoles, and I’d suggest to wait a week (or so) before applying to your production environments, but there are some really cool  features.

The pick of features for me at the moment are:

Application groups

Create a group of applications that you can send to a user or device collection as a single deployment. The metadata you specify about the app group is seen in Software Center as a single entity. You can order the apps in the group so that the client installs them in a specific order.

This feature is pre-release.

Install an application for a device

From the Configuration Manager console, you can now install applications to a device in real time. This feature can help reduce the need for separate collections for every application.

Task sequence debugger

The task sequence debugger is a new troubleshooting tool. You deploy a task sequence in debug mode to a collection of one device. It lets you step through the task sequence in a controlled manner to aid troubleshooting and investigation.

Clear app content from client cache during task sequence

In the Install Application task sequence step, you can now delete the app content from the client cache after the step runs.

Reclaim SEDO lock for task sequences

If the Configuration Manager console stops responding, you can be locked out of making further changes to a task sequence. Now when you attempt to access a locked task sequence, you can now Discard Changes, and continue editing the object.

Pre-cache driver packages and OS images

Task sequence pre-cache now includes additional content types. Pre-cache content previously only applied to OS upgrade packages. Now you can use pre-caching to reduce bandwidth consumption of:

  • OS images
  • Driver packages
  • Packages

For more information, see Configure pre-cache content.

Improvements to OS deployment

This release includes the following improvements to OS deployment:

  • Use the following two PowerShell cmdlets to create and edit the Run Task Sequence step:
    • New-CMTSStepRunTaskSequence
    • Set-CMTSStepRunTaskSequence
  • It’s now easier to edit variables when you run a task sequence. After you select a task sequence in the Task Sequence Wizard window, the page to edit task sequence variables includes an Edit button. For more information, see How to use task sequence variables.
  • The Disable BitLocker task sequence step has a new restart counter. Use this option to specify the number of restarts to keep BitLocker disabled. This change helps you simplify your task sequence. You can use a single step, instead of adding multiple instances of this step. For more information, see Disable BitLocker.
  • Use the new task sequence variable SMSTSRebootDelayNext with the existing SMSTSRebootDelay variable. If you want any later reboots to happen with a different timeout than the first, set this new variable to a different value in seconds. For more information, see SMSTSRebootDelayNext.
  • The task sequence sets a new read-only variable _SMSTSLastContentDownloadLocation. This variable contains the last location where the task sequence downloaded or attempted to download content. Inspect this variable instead of parsing the client logs.

More frequent countdown notifications for restarts

End users will now be reminded more frequently of a pending restart with intermittent countdown notifications. You can define the interval for the intermittent notifications in Client Settings on the Computer Restart page. Change the value for Specify the snooze duration for computer restart countdown notifications (hours) to configure how often a user is reminded about a pending restart until the final countdown notification occurs.

Additionally, the maximum value for Display a temporary notification to the user that indicates the interval before the user is logged off or the computer restarts (minutes) increased from 1440 minutes (24 hours) to 20160 minutes (two weeks).

For more information, see Device restart notifications and About client settings.

Software updates

Additional options for WSUS maintenance

You now have additional WSUS maintenance tasks that Configuration Manager can run to maintain healthy software update points. The WSUS maintenance occurs after every synchronization. In addition to declining expired updates in WSUS, Configuration Manager can now:

  • Remove obsolete updates from the WSUS database.
  • Add non-clustered indexes to the WSUS database to improve WSUS cleanup performance.

For more information, see Software updates maintenance.

Configuration Manager console

Role-based access for folders

You can now set security scopes on folders. If you have access to an object in the folder but don’t have access to the folder, you’ll be unable to see the object. Similarly, if you have access to a folder but not an object within it, you won’t see that object. Right-click a folder, choose Set Security Scopes, then choose the security scopes you want to apply.

For more information, see Using the Configuration Manager console and Configure role-based administration.

If you want to get your hands on 1906, for the time being you’ll need to run the PowerShell script enableearlyupdatering1906.ps1, on your site server, which can be found here

SCCM – Windows 10 no longer ticked as deployment target OS for packages and TS’s after upgrade to current branch

This is a follow up to this post : https://blog.adexis.com.au/2019/06/14/sccm-powershell-errors-after-moving-primary-site-server-via-site-failover/ 

 

Another issue i ran into this upgrade – which was far more interesting, was that all packages and task sequences which had windows 10 ticked within their “supported platforms” – the tick was now gone after upgrade.

 

Now, before we go any further, i should state that i am dead against using this functionality in programs and task sequences – i see it create way more hassle than help where-ever clients use it…. if you want to limit, use a limiting collection or exclude collections on your targets…. additionally – if you are still using packages – get with the times, move to applications!

That being said, this client did have multiple outsourcers in their environment, lots of politics and bafflingly bad decisions (how bad? they have DP’s on DC’s…. yes… absolute insanity) – so while i would prefer that setting wasn’t used – the guys that utilise SCCM just wanted what they had back – and fair enough too.

Now, back to the issue.

in order to troubleshoot, i ticked the win 10 box within a dummy package/program and compared it to one of the broken ones – this was done using

Get-CMPackage -id <package ID> -fast | Get-CMProgram | select –expandproperty SupportedOperatingsystems

the output you’ll get will be something like this

SmsProviderObjectPath : SMS_OS_Details

MaxVersion            : 10.00.9999.9999

MinVersion            : 10.00.0000.0

Name                  : Win NT

Platform              : I386

 

SmsProviderObjectPath : SMS_OS_Details

MaxVersion            : 10.00.9999.9999

MinVersion            : 10.00.0000.0

Name                  : Win NT

Platform              : x64

 

SmsProviderObjectPath : SMS_OS_Details

MaxVersion            : 6.10.9999.9999

MinVersion            : 6.10.0000.0

Name                  : Win NT

Platform              : x64

 

SmsProviderObjectPath : SMS_OS_Details

MaxVersion            : 6.20.9999.9999

MinVersion            : 6.20.0000.0

Name                  : Win NT

Platform              : x64

 

on the one that was manually ticked – the output was this (cut down to win 10 for sake of post length)

SmsProviderObjectPath : SMS_OS_Details

MaxVersion            : 10.00.99999.9999

MinVersion            : 10.00.0000.0

Name                  : Win NT

Platform              : x64

 

The difference is subtle – but there. The broken one has 4 x 9’s in the middle, the “correct” one has 5 x 9’s in the middle…. at some stage during the CB’s – the Maxversion of windows 10 obviously changed – and for reasons im still not sure about – the upgrade process did not correctly update them.

This can also be viewed by directly viewing the SQL table dbo.PKGProgramOS . Program names with “*” are for task sequences.

There were a couple of ways to address this.

Initially, i looked at using powershell and doing everything through the SMS provider, so everything would be supported. The downside of this is that there was no way to delete/change the stuffed entry – only to add the correct entry.

Working the script out really sucked, as when using get-CMSupportedPlatform on 1902, there are multiple windows 10 entries, including “All windows 10 (64-bit)” – which doesn’t work when piped into a script… instead, you have to use “All windows 10 (64-bit) Client” – sure, it seems logical now… but i, and one of my team spent hours on that!

Once that was sorted, the plan was to use a script such as: (the below was never completed, tested or implemented, so its below for a conceptual reference only! it does not work!)

$programs = Get-CMPackage -fast | Get-CMProgram | select packageID, PackageName, PackageVersion, ProgramName -expandproperty SupportedOperatingsystems

$win10x64 = Get-CMSupportedPlatform -fast -Name “All Windows 10 (64-bit) client”

write-host “Programs: ” $programCount.count -ForegroundColor Green

foreach ($program in $programs) {

if ($program.MaxVersion -eq “10.00.9999.9999”) {

write-host $program.PackageID $program.PackageName $program.PackageVersion  $program.ProgramName $program.MaxVersion $program.Platform

if ($program.Platform -eq “x64” {

Set-CMProgram -PackageName $program.PackageName -StandardProgram -ProgramName $program.ProgramName -AddSupportedOperatingSystemPlatform $Win10x64

}

}

 

Fortunately, this client has an awesome database guy (thanks Alan) when was able to help in a much more sensible way – updating the SQL table directly.

While this is unsupported by MS (use at your own risk etc etc) – since MS support has basically become completely useless… their products are effectively unsupported anyway. It takes 2-3 weeks to get through the first lines of support to someone with a brain – and dont get me wrong, when you get to that person – they can be fantastic…. but the time frame is just unrealistic.

With that in mind, we made a copy of the dbo.PKGProgramOS table and then ran the following sql (comments included)

–First step is to backup all the records that could potentially be changed by the script.
–This table, PkgProgramOS_49s_20190603, can then be removed in a few days/weeks depending on the thoroughness of user acceptance testing
— NB – all the commented out “.PkgID = ” lines were used to test the logic prior to updating the records
–Count of records found (2 different runs)
–6836, 6777
SELECT *
INTO PkgProgramOS_49s_20190603
FROM [CM_C01].[dbo].[PkgProgramOS] (nolock) y
where 1=1
–and y.PkgID = ‘00100050’ –‘C01008EE’
and OSMaxVersion = ‘10.00.9999.9999’

–Confirmation that expected number of records are in the backup table. Measure Thrice Cut Once!
select * from PkgProgramOS_49s_20190603; –6777

–This is the select version of the update to bring back and confirm all records that will be updated.
–Requirement was to update all 10.00.9999.9999 records to be 10.00.99999.9999 where there was not already a 10.00.99999.9999.
–i.e. Update where all Package/OS/Program records with the 4 Nines to be 5 Nines, except where there was already a 5 Nines to prevent creating a duplicate 5 Nine.
–Join the Set of 4 Nine records with those with 5 Nines and return those with out the 5 Nine record
–Count of Records found
–6835, 6776
SELECT x.[PkgProgramOS_PK]
,x.[PkgID]
,x.[ProgramName]
,x.[OSName]
,x.[OSPlatform]
,x.[OSMinVersion]
,x.[OSMaxVersion]
,n.PkgProgramOS_PK, n.OSMaxVersion, n.OSPlatform, n.PkgID, n.ProgramName
FROM [CM_C01].[dbo].[PkgProgramOS] (nolock) x
LEFT OUTER JOIN ( — Records with 5 Nines
SELECT y.[PkgProgramOS_PK]
,y.[PkgID]
,y.[ProgramName]
,y.[OSName]
,y.[OSPlatform]
,y.[OSMinVersion]
,y.[OSMaxVersion]
FROM [CM_C01].[dbo].[PkgProgramOS] (nolock) y
where 1=1
–and y.PkgID = ‘C01008EE’
and y.OSMaxVersion = ‘10.00.99999.9999’
) n on x.PkgID = n.PkgID and x.OSName = n.OSName and x.OSPlatform = n.OSPlatform and x.ProgramName = n.ProgramName
where 1=1
–and x.PkgID = ‘C01008EE’–00100050
and x.OSMaxVersion = ‘10.00.9999.9999’ and isnull(n.OSMaxVersion,”) <> ‘10.00.99999.9999’ –Include 4 Nines and Exclude where a 5 Nine is found.

–Update version of the above Select.
–Always create the select, then copy and paste and convert to an update, that way the condition is always in place
–(This prevents the tragic error of writing update table set value =, and then finger slipping and hitting F5, before the where clause is added!)
UPDATE x set [OSMaxVersion] = ‘10.00.99999.9999’
FROM [CM_C01].[dbo].[PkgProgramOS] x
LEFT OUTER JOIN (
SELECT y.[PkgProgramOS_PK]
,y.[PkgID]
,y.[ProgramName]
,y.[OSName]
,y.[OSPlatform]
,y.[OSMinVersion]
,y.[OSMaxVersion]
FROM [CM_C01].[dbo].[PkgProgramOS] (nolock) y
where 1=1
–and y.PkgID = ‘C01008EE’
and y.OSMaxVersion = ‘10.00.99999.9999’
) n on x.PkgID = n.PkgID and x.OSName = n.OSName and x.OSPlatform = n.OSPlatform and x.ProgramName = n.ProgramName
where 1=1
–and x.PkgID = ‘C01008EE’–00100050
and x.OSMaxVersion = ‘10.00.9999.9999’ and isnull(n.OSMaxVersion,”) <> ‘10.00.99999.9999’
–6776 — Records updated. Ooh look it matches our select!

–Run the select to find if any 4 Nine records are left.
SELECT *
FROM [CM_C01].[dbo].[PkgProgramOS] (nolock) y
where 1=1
–and y.PkgID = ‘00100050’ –‘C01008EE’
and OSMaxVersion = ‘10.00.99999.9999’
–Pass the system back to the users for testing

 

After this – the programs and task sequences that previously had “All windows 10 32bit” (and 64bit) ticked will have it ticked again.

Clients that have evaluated these programs already will have the following status – Program rejected (Wrong Platform)

 

In order to get around this, simply update any properties of the program e.g. the estimated run time (for example) – this will force clients to re-evaluate the package – and with the fixed “supportedOperatingsystem” entry – this will now run correctly.

SCCM powershell errors after moving primary site server via site failover

Recently i completed a somewhat challenging SCCM upgrade from:

SCCM 2012 R2

Server 2008

SQL 2008 R2

2 SMS providers, 2 MP’s, 130-odd DP’s, SMP’s

33,000 odd clients

 

to:

SCCM CB (1902 at time of upgrade)

Server 2016 (latest the outsourcer would support)

SQL 2016 (latest the outsourcer would support)

Site server failover

 

i know its not big by worldwide standards – but for a small town like Adelaide – its pretty reasonable.

 

all-in-all it was a good project…. too much politics for my liking due to multiple outsourcing agreements – but it went quite smoothly.

 

There were a few somewhat unique issues i ran into which i think are worthy of blogging… they’re a bit obscure – and i’m not sure many other people will have them, but hey – if this find and helps a few people – all the better.

So – after completing the move to the new servers, there were still SMS providers and management points on two “old” servers. When decommissioning these, some minor errors started to occur.

When opening powershell from the SCCM console after the SMS providers were uninstalled, it still worked, but one of the following errors would appear:

Import-Module : The SMS provider reported an error

or

Import module : A drive with the name <sitecode> already exists

I checked a number of things, initially thinking that maybe the SMS providers had not uninstalled correctly (even though everything reported correctly in the logs)

First – The table in the SQL database which holds this data is “smsdata” – viewing this confirmed the provider was correct

Next – WMI – using WBEMtest, point it at the root\SMS namespace on the site server and failover site server, then enumerate the class “SMSProvider” – the correct SMS providers showed up here too.

Next – i had a look at the registry on a machine with the console installed and noticed HKEY_CURRENT_USER\SOFTWARE\Microsoft\ConfigMgr10\AdminUI\MRU still had the “old” server listed… once the entry to the “old” server was removed, the errors stopped occurring

In follow up to this, there were still complaints about new users going to the “old” site server by default. This can be updated in HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\ConfigMgr10\AdminUI\Connection\Server (on x64 machines…. which i would be surprised if there are admins out there not running x64)

These changes could be performed manually, or via SCCM, but my preference is via group policy preferences. Check for the existence of the console, if it exists, then delete the hkCU key and update the HKLM value

This one was not a big one – powershell still worked after the initial error, the console exhibited no issues – but removing warnings/errors where-ever possible is always good.

 

Deploy Win32 applications with Intune

from http://www.scconfigmgr.com/2018/09/24/deploy-win32-applications-with-microsoft-intune/

WIN32 APPLICATION DEPLOYMENTS

The ability to “package” applications for deployment in Microsoft Intune is something that has been highly requested by many organisations making the move to management of devices through Intune. Although there is a fundamental difference in deploying applications through Configuration Manager and Intune, Microsoft is developing tools to provide similar functionality across the management stack. Up until now it it has been possible to deploy applications through Intune, this relied on a single MSI installation file with no external dependencies. In some cases this meant that repackaging of applications was the only method of deploying those business applications, thus being a time consuming process.

Today it is now possible to deploy applications through Intune without those restrictions, this process creates a packaged container of the setup files along with command line installation and uninstall commands.

 

This is a significant feature towards bringing Intune from the realms of “good for mobile device management only” to “also good for desktop management”.

SCCM currently does (and probably will for quite a while) have additional functionality which larger enterprises require – however, this is a good step in allowing smaller organisations more flexibility in their deployment options.

 

Note: as of 25/9, this feature is available with an Intune tenant running a preview of the GA release.

Execution status received: 24 (Application download failed)

I came across an interesting issue today where I couldn’t get applications to install on a specific piece of hardware during a task sequence. All task sequence steps would run fine, other than ‘Application’ installs – and they would work fine on other hardware.

Looking in the smsts.log file, I could see the following error for each application:
Execution status received: 24 (Application download failed)

I checked the boundaries, everything was good. Google has many instances of the same issue, but none seemed to have relevant (or helpful) solutions. In the end, I realised this device has 4G LTE with a valid SIM in it, and it was connecting automatically during the task sequence. It seems this was confusing it and it couldn’t locate the content for applications!

The simplest solution I could find was to disable the NIC during the task sequence, then re-enable it at the end. The following are the powershell commands I put in the task sequence to get it working:

To Disable: powershell.exe -ExecutionPolicy Bypass -Command “Get-NetAdapter | ?{$_.MediaType -eq ‘Wireless WAN’} | Disable-NetAdapter -Confirm:$False

To Enable: powershell.exe -ExecutionPolicy Bypass -Command “Get-NetAdapter | ?{$_.MediaType -eq ‘Wireless WAN’} | Enable-NetAdapter -Confirm:$False

Update 1806 for Configuration Manager current branch is now available

ConfigMgr 1806 was released yesterday morning https://cloudblogs.microsoft.com/enterprisemobility/2018/07/31/update-1806-for-configuration-manager-current-branch-is-now-available/

Couple of nice usability features:

CMPivot, building off our real-time script capability.  CMPivot is a new in-console utility that provides access to real-time state of devices in your environment.

With CMPivot, you can get instant insights into your environment.  Need to know your current compliance state in real-time?  CMPivot can get you those insights in minutes.

Third-party software updates – You can subscribe to partner catalogs in the Configuration Manager console and publish the updates to WSUS using the new third-party software updates feature. You can then deploy these updates using the existing software update management process.

Uninstall application on approval revocation – After enabling the optional feature Approve application requests for users per device, when you deny the request for the application, the client uninstalls the application from the user’s device.

Configure a remote content library for the site server – You can now relocate the content library to another storage location to free up hard drive space on your central administration or primary site servers or to configure site server high availability.

View the currently signed on user for a device – You can see a column for the currently logged on user now displayed by default in the Devices node of the Assets and Compliance workspace.

 

Note: As the update is rolled out globally in the coming weeks, it will be automatically downloaded, and you will be notified when it is ready to install from the “Updates and Servicing” node in your Configuration Manager console. If you can’t wait to try these new features, this PowerShell script can be used to ensure that you are in the first wave of customers getting the update. By running this script, you will see the update available in your console right away.

Creating large stand-alone media from SCCM – issues when the HP SPP 2018.03 is a package in the TS

We often create one task sequence for all workstation builds and another for all server builds, utilising task sequence variables to perform the decision making within the task sequence.

One of the downsides of this is that the task sequence binaries can get quite large, especially for server builds where we have current and legacy versions of the HP SPP, the Dell SUU and (at a minimum) server 2012 R2 and server 2016.

This isn’t an issue for network based builds, as non-required content is simply skipped, however, for media builds, it can lead to 40GB+ requirements, which the SCCM console doesnt handle well.

This is where Rufus comes in.

Rufus can help out by allowing use of larger hard drives (just tick the “list USB hard drives” option) and can apply bootable iso’s generated by SCCM (utilising the “unlimited size” option) to a USB hard drive.

This has been incredibly useful for us in the past, utilising large hard drives as USMT stores at slow link sites for client deployment.

In this instance, ive been using Rufus to apply a 50GB server build iso to a hard drive, but keep getting presented with a warning

“This ISO image seems to use an obsolete version of ‘vesamenu.c32’. Boot menus may not display properly because of this.”

Irrevelant of how you proceed (allow Rufus to download an update or not), the drive is not bootable.

Upon investigation of the rusfus logs and the resultant media, i found that syslinux.cfg was actually pointing to my HP SPP package.

This forum post then confirmed that Rufus is finding a syslinux.cfg, assuming that it is “real” bootable media and hence the ‘vesamenu.c32’ prompt.

After a few hours of troubleshooting and trying to get around it, i simply removed the “usb” and “system” folders from my HP SPP packages (as we wont be booting to it ever, its only for use in SCCM), re-created my standalone media iso – then used Rufus to write the bootable iso to the USB HDD, this time with no issues.

I realise this is a fairly obscure issue , but hopefully it helps someone.

 

 

Speed up offline servicing

Currently i am creating some server builds for a place which will be deploying large numbers of servers over the coming months.

One of things that is/was taking up a great deal of time was offline servicing for the base OS, primarily because the SCCM server is currently sitting on a virtual environment with disk that is struggling. With 2016, this isn’t so bad, as due to cumulative updates, there are only a few updates to be installed. With 2012 R2 however, there is a large number of updates – and the process continually fails due to the poor performance of the server.

One of things you can do to speed this process up is to remove unused images from your wim.

Both Server 2012 R2 and 2016 come with 4 images (with an index of 1 to 4) within the install.wim. These generally correlate with:

  • Index1 – Server 2012R2/2016 standard core
  • Index2 – Server 2012R2/2016 standard desktop experience
  • Index3 – Server 2012R2/2016 datacentre core
  • Index4 – Server 2012R2/2016 datacentre desktop experience

If you view Logs\OfflineServicingMgr.log during an offline servicing operation, you will notice lines that state things such as:

Applying update with ID xxxxxx on image at index 1

Then the same update will apply to image 2,3 and 4. In this enviornment, we are not deploying server core, so we only need indexes 2 and 4 (standard and datacentre with desktop).

We can view the indexes available within the wim by typing:

dism /get-imageinfo /imagefile:E:\<path to wim>\Install.wim

Then, if you dont need indexes 1 and 3 (as we dont in this scenario)

dism /delete-image /imagefile:E:\<path to wim>\Install.wim /index:1
dism /delete-image /imagefile:E:\<path to wim>\Install.wim /index:3

Now when you use offline servicing, each update will only be compared against 2 images, instead of 4, significantly reducing the processing time/disk usage, especially for 2012 R2 (where there are a large number of updates to apply)

This can also be used for client OS’s, such as Windows 10.

One important note – this will not reduce the size of the WIM. It will simply remove the index and save you time for offline servicing.

If your image is already in SCCM, then you must

  1. Go to Software Library | Operating systems | Operating system images
  2. Right click on the appropriate image | properties | Images tab
  3. Click on “reload”, then notice the dropdown has been reduce from 4 index’s, then hit “ok” to exit.
  4. Go into your task sequence
  5. Update the image index as required.

The importance of cleaning up WSUS – even if your are only using it for SCCM

In the distant past, we would generally say to clients “Leave WSUS admin alone – the SCCM settings will take precedence, so there is no point in using it”

As the years have passed, and the number of updates available has grown considerably, this is no longer the case. The SCCM settings still take precedence, however the pure number of updates has gotten so large that it can cause performance issues for the SCCM server – and even the IIS timeout to expire when SCCM is syncing updates. This generally results in and endless loop and 100% CPU for w3wp.exe.

Unfortunately, trying to list the updates in the WSUS console will often lead to the console crashing and the dreaded prompt to “reset server node”.

The best way to address this, isn’t really one of the many articles you will find by googling “sccm high CPU w3wp.exe” (or similar). Generally these will suggest modifying a number of entries in your IIS config to increase time outs, etc – these can assist, but they don’t really address the root cause of the issue – which is simply the huge number of updates.

The best way to resolve this is to simply reduce the number of updates shown in WSUS. This will reduce your memory usage, reduce the number of updates that SCCM has to scan each time, and generally put less load on your server.

There are two ways you can go about this:

 

The manual method

If you have the resources available, I’ve found increasing the RAM and CPU count on the SCCM server temporarily can help allevate the issue of the “reset node” issue.

Once you get in (it may take a few attempts), go to ‘updates’ > ‘all updates’, set the search criteria to “Any except declined” and “any” and hit refresh. Once loaded, add the “supersedence” column to the view and sort by that.

Decline all updates that are superseded. If you don’t clean up regularly, this number could be very high.

After this, you can create views to decline updates for products you no longer use (e.g. Windows 7 and Office 2010) or search for things including “beta”, “preview” and “itanium” and decline those updates as well.

After all that is done, run the server cleanup wizard. You will likely need to do this a number of times, as if your server is struggling already, this also will struggle to complete (and it seems to be quite poorly coded to handle large numbers of updates on low end servers)

 

The scripted method

A guy called “AdamJ” has written a very useful script which you can get at https://community.spiceworks.com/scripts/show/2998-wsus-automated-maintenance-formerly-adamj-clean-wsus . I know, I can see some of you recoiling at the suggestion of using a user submitted spiceworks script… they do have a whole bunch of people (just like the MS forums) suggesting to use “sfc /scannow” for anything and everything – which is a sign of a non-enterprise tech that has NFI… however, this script is really very good – and something I’ve been using for approx 2 years, with nothing but good things to say about it.

You can run it with the “-firstrun” parameter and it will, by default, clean out superseded updates – which is the main cause of huge update numbers, but it will also grab the ever annoying itanium, preview and expired updates. At approx line 629 of the script, you can also configure it to remove IE7,8,9,10 updates, Beta updates etc (or if you are one of the few people in the world with itanium, keep itanium updates!).

This script, unlike the console, will keep plugging away… and if it should happen to get stopped for whatever reason, will resume where it left off.

When removing obsolete updates, I have seen some clients (with lower spec servers) where this process can take a long time, so long that you may have to leave it overnight (or over the weekend), and sometimes restart the process.

This process will get you a fair chunk of the way, and allow you to then open the WSUS console and decline further updates, such as products you no longer use (Windows 7 and office 2010 are reasonably common ones these days), x86 updates if you have an all x64 environment, and in the case of Win 10, updates that no longer apply to you (e.g. if your entire fleet is on Win 10 1609 and 1703, you don’t need the 1511 updates)

After all this is complete, you do need to run the server cleanup wizard again – which does frequently crash and end up with the “reset server node” error. So you can re-run the WSUS cleanup script, or simply run the server cleanup wizard multiple times.

 

My experiences using these methods

I’ve found that in environments that were previously at 100% CPU, they start working again, and environments that were massively over-specc’d that didn’t have the high CPU issue went from using 6gb of RAM for the w3wp.exe process down to 500mb. This will obviously vary from environment to environment.

After this process is completed, you should be able to get into the WSUS console and run the server cleanup wiazrd, without crashes.

If you’re interested, you can also sync SCCM software updates and look at the wsyncmgr.log and see the far smaller list of updates it will sync against now.

Longer term, the AdamJ script does have monthly options that you can schedule in, or for our clients that are uncomfortable with that, simply get in and clean up once every 3 months or so, so you list of updates doesn’t get out hand.

The first cleanup is the biggest, after that, performing the same operations once every 3 months is plenty, and if you forget about and it happens to be once every 6 months instead, you’ll still be fine.

 

Taking it a step further – shrinking the SUSDB

One of the things which the AdamJ cleanup script does is truncate the SQL table “tbEventInstance” which uses up the majority of space in most WSUS databases that have been in use for a while.

If you are not comfortable with a script doing this, you can connect to the database and execute the following query against the “SUSDB” database – “truncate table tbEventInstance”.

If the DB is on a full version of SQL (which, if your running SCCM, i would argue the SUSDB should be on the same SQL instance, rather than installing an additional windows internal database), you can then create a maintenance plan to reindex, shrink etc the database.

If you are using Windows internal database, you can still install SQL management studio, then connect to “\\.\pipe\MICROSOFT##WID\tsql\query”, from there you can execute the truncate, shrink the database etc. Keep in mind that you cannot use maintenance plans with Windows internal databases.

 

What about large enviornments where you do require a wide range of updates ?

In large environments, you may not be able to decline entire product sets for extended periods (e.g. its relatively easy to move everyone onto Windows 10 (and get rid of all Win 7) for 2,000 PC’s, but not so easy for 50,000 PC’s), however, many of the points in this article still hold true.

  • The largest reduction in updates will still come from superceded updates
  • Language packs are another area where there’s lot’s of opportunity for reduction (e.g. if you require english and french – there are many other languages that can declined)
  • Ensure your SUSDB is on your full SQL instance…. that way you are running one less database instance (and therefore utilising less resources) and also have maintenance plans at your disposal
  • Use a maintenance plan to keep your SUSDB database optimal

 

SCCM Update Cleanup

It’s also worth noting that once the SUSDB has been cleaned up, SCCM will execute its own cleanup after the next sync. This cleanup removes obsolete Update CIs (Configuration Items) that corresponded to the items removed from the SUSDB. In most environments, this isn’t usually something noticeable, however in severely under resourced SCCM servers it can cause its own set of problems (though there’s not a huge amount you can do about it other than wait). This will generally present as the SCCM console locking up while it’s doing back-end SQL processes – and if you look at the SQL threads, you’ll see a WSUS related one blocking all other threads. Realistically your best option to resolve this is to increase the resources available to the server – and if that isn’t a possibility, settle in for a long wait!

Microsoft Surface Laptops and SCCM OS Deployment

So you’ve just picked up your shiny new Microsoft Surface Laptop and want to put your current Windows 10 Enterprise SOE on it. Of course you have it all set up in SCCM (right?), so you figure you’ll kick off a build and be up and running in a half hour or so.

Granted, the Surface Laptop isn’t marketed as an Enterprise device and comes with Windows 10 S pre-installed, but you can do a simple in-place upgrade to Windows 10 Pro. So obviously it should be capable of running any of the Windows 10 OS’s (which it is).

Unfortunately it’s not quite so simple to get them to build through SCCM. Below are the three issues I experienced when trying to build one via SCCM (and was silly enough to think it’d be straight plug and play!):

  • PXE doesn’t work. I’ve got a couple of USB to Ethernet adapter that works fine with PXE on other devices – but they simply don’t work with the Surface Laptop. Updated the firmware on the laptop to the latest (as Surface Pro’s had similar issues with old firmware), and still had the same issue. Whether this is unique to the Surface Laptop I have, or all of them – I’m not sure (as I’ve only got the one so far).
  • The keyboard doesn’t work in WinPE. Touchpad mouse works fine – so you can kick off the task sequence – you just can’t use the keyboard at all. Fine if your task sequence is fully automated, but if you need to enter a computer name or troubleshoot issues, you’re going to need to import some drivers.
  • SecureBoot. Once I’d decided to use a bootable USB to kick off the task sequence, it started running through fine. Rebooted into Windows Setup, then proceeded to complain about the “Microsoft-Windows-Deployment” component of the Specialize pass in the Unattend.xml. Long story short, it’s caused by SecureBoot (more on this further down).

So lets break this down into how to fix each.

PXE: Simply put, I haven’t been able to fix this. Updated firmware, used different PXE capable USB to Ethernet devices. As above, I’m not sure if this is just the one I have, or all of them – or even if it’ll be fixed in newer firmwares. At this stage, it looks like the only option is SCCM boot media. Since the Surface Laptop only has a single USB port, you’ll either need to use a USB/Ethernet combo (like one of these – not sure if they’re PXE capable or not, haven’t tested), or you’ll need to use an external USB hub. Note: you can initiate PXE from full power off by pressing Volume Down + Power. If you want to USB boot, you need to go into the UEFI setup by pressing Volume Up + Power. On the boot settings page, you can swipe left on any of the boot options to initiate a ‘boot now to selected device’.

SecureBoot/Unattend.xml: This one is a little more tricky. Essentially if you look at the setupact.log file, you’ll see something along the lines of “[SETUPGC.exe] Hit an error (hr = 0x800711c7) while running [cmd / c net user Administrator /active:yes]“. 0x800711c7 translates to “Your organization used Device Guard to block this app”. According to this Microsoft article, it’s due to the Code Integrity policy in UEFI being cleared as part of the OS upgrade (from Windows 10 S to something else). Since Windows 10 S won’t let you launch certain executables, it blocks them during the OS Deployment as well. Supposedly fixed by a reboot – but by then you’ve broken your OS deployment. The obvious fix is to disable SecureBoot, then re-enable it after the task sequence completes. I’m not really a fan of this approach, and I’m not sure how you’d automate it (even if you could).

During my research, I found a reference to someone suggesting that applying the Surface Laptop drivers during the OS Deployment actually fixes the issue. I’m not 100% sure if this is the case – as I disabled SecureBoot, rebooted and re-enabled SecureBoot before testing out this process – but doing so afterwards did actually work (with SecureBoot enabled). Since I’ve only got the one device so far, I’ll update this blog once I’ve tested on others. I’ve put some instructions further below on how to import the drivers into SCCM (as they’re provided in MSI format now, and you’ll need them to apply before Windows Setup).

Keyboard during WinPE: Essentially, you need 5 drivers imported into the boot image for the keyboard to work (as detailed by James in this technet blog) Below is an image of the drivers required in the boot image:

Adding Surface Laptop Drivers to SCCM

Surface drivers all now come in MSI format – which is good for normal deployments, but doesn’t really help you for OS Deployments (assuming you want to apply the drivers prior to Windows Setup). After downloading the latest Surface Laptop drivers from Microsoft, you can use the following example command to extract them (which goes from around 300MB to a whopping 1.3GB):

msiexec.exe /a C:\Temp\SurfaceLaptop_Win10_15063_1802008_1.msi targetdir=C:\Temp\Extract /qn

From there you can import the “Drivers” sub-folder into SCCM as per usual. If you plan on applying them as a proper ‘Driver Package’ during the OS Deployment, you’ll need to import them into their own driver package, distribute it to the relevant Distribution Points, then add it to the task sequence. You can use the following WMI query to filter it to just Surface Laptops:

SELECT * FROM Win32_ComputerSystem WHERE Model LIKE “%Surface Laptop%”

Obviously you can now also add the keyboard drivers to the required boot image!