Wrapping USMT for a more flexible user profile Backup/Restore process

I’ve done a bit with the User State Migration Tool (USMT) for both migrating and archiving user data. Instead of using the USMT integration process with SCCM, i needed something a bit more flexible that would potentially allow profile restores to multiple machines.

One of the scenarios I needed to support was user initiated backup and restore of the current user profile. To support this and meet the requirements, I needed the following things:

  • Multiple profile backups must be permitted. If a user performs a profile backup and doesn’t restore the data, the user must be able to backup their profile again without requiring outside intervention.
  • Previous profile backups should be stored for a time, as users may forget to restore or files may need to be recovered from the USMT store.
  • When a restore is done, the latest profile backup for that user should be restored. This allows previous backups to exist for IT to recover files from if required.
  • Users don’t necessarily have administrative rights, so the solution must run as the local system to backup the current user.

The current script is designed to run either as an SCCM application, or from a task sequence to get the most recent logged on user and backup that profile only, along with the SYSTEM profile (to catch files stored in the root C:, as an example). Restore is to work the same way and unpack the most recent profile backup onto the destination machine it is run on.

Backing up the current user profile when running as SYSTEM presented a bit of a challenge, as the script will need to be told to backup just the logged in user. In order to give this information to USMT, we need to investigate the Win32_UserProfile  WMI class, to see who’s logged on. It does this by being passed the domain SID of users that might log onto the machine, then filtering the instance of Win32_UserProfile to get the most recently logged on username. From there, you can store the user profile, or select the most recent profile backup for restore.

Here’s two scripts I call from task sequences to give user initiated scan and load tasks. This gives the users the ability to self-service their own backups and restores with no intervention from IT.

 

SCCM – Updating and configuring HP BIOS/UEFI in a task sequence – An update

Lately I’ve bee working on a little more SCCM operating system deployment work and I’ve got an updated toolset for configuring and updating UEFI firmware for HP machines easily in a task sequence. This is a reasonably long post, so bear with me.

A lot of the same techniques from my earlier posts on the subject apply. We are still using HPBIOSUPDREC, BiosConfigUtility and an SCCM package for the source files. I’ve updated the batch files to take an argument for the configuration or update file, as well as the previous architecture detection. The good thing about this method is that it supports all current HP laptop, desktop and workstation models with no change, you just give the update file, or the configuration as an argument and away you go.

I considered using PowerShell for this, however it takes a little while to start in WinPE and unless I add more logic to the process for particular models or action types, I don’t see the need to convert it yet.

I’ve set up the package for HP machines I need to configure and update as follows:

SCCMPackages\HP-UEFI\
    68ICF.CAB (UEFI firmware - EliteBook 8x70p)
    BiosConfigUtility.exe   (BIOS config utility - x86)
    BiosConfigUtility64.exe (BIOS config utility - x64)
    BIOSPW.bin              (Encrypted BIOS password)
    ConfigureUEFI.cmd (UEFI config command file)
    EliteDesk800G2-Win7.cfg (UEFI configuration - Win 7)
    EliteDesk800G2-Win10.cfg (UEFI configuration - Win 10)
    EliteBook8x0G3-Win7.cfg (UEFI configuration - Win 7)
    EliteBook8x0G3-Win10.cfg (UEFI configuration - Win 10)
    EliteBook8x70p-Win7 (UEFI configuration - Win7)
    N75_0110.bin (UEFI firmware - EliteBook 8x0 G3)
    N21_0219.bin (UEFI firmware - EliteDesk 800 G2 SFF)
    UpdateBIOS.cmd (UEFI update command file HPqflash models)
    UpdateUEFI.cmd (UEFI update command file HPBIOSUPDREC models)

A sample set of files for all of this can be found on GitHub, except the HP binaries and firmware, which need to be downloaded from HP.

You can follow the larger package format, with all models together, or spread the update and configuration files over multiple packages, whichever suits your requirements best.

You may notice that I’ve included an odd DLL file ‘oledlg.dll’. This is needed to make HPqflash work on WinPE 10 (10.0.10586.0). If you run HPqflash in WinPE 10 without it, you get an exit code of -1073741515 (0xC0000135), which means a DLL needed for the program is missing.

I did a bit of investigation with procmon on a full windows system and found oledlg.dll was required, but missing from WinPE. I put this DLL in the same folder next to HPqflash and all was good!

Both ConfigureUEFI.cmd and UpdateUEFI.cmd are general for all models using HPBIOSUPDREC and the HP BIOS config utility and look like this:

There’s also a slightly different version for deploying updated firmware, if you’re still using HPqflash:

We can use the same SCCM ‘Run command line’ task we used in the past for this, with a little tweak to run the command file with the right update or configuration. This is done in the same way as before, with the extra exit code for successful completion.

This is the configure command line:

command-line-configure

Followed by the update command line, along with the success exit codes shown.

command-line-update

update-exit-codes

The update command line needs to follow the configure step if as it requires a password bin file.

Hopefully this has been helpful updating things in the journey to support newer HP models.

Working towards contributing more code

Not long after my first PowerShell gallery submission, which i’m glad will be made redundant after PowerShell 5.1 ships with Get/Set-Timezone cmdlets, it’s time for another post on contributing!

I’ve been working on some build scripts, both privately and in public with my Timezone module and I realised it was about time I contributed some of this to other projects that might benefit from the code.

I found that some of my work around script signing could be contributed directly back to one of the projects I used code from, the Plaster project! It was good fun doing it and the feedback I got back was great.

Anyways, if you haven’t checked out the Plaster project, it’s definitely worth checking out and i’ll definitely be making time to contribute more to community projects in the future.

Synchronizing DHCP reservations between two DHCP servers serving the same scope

As part of a DHCP server upgrade to Server 2012 R2, I needed to consolidate the reservations created between a single DHCP scope spread over two servers so I could have a definitive reservation list for the upgrade.

Here’s the script I wrote to do it.

You can use the function to add the DHCP reservations to the other DHCP server, or record the output with something like the following.

Get-UnmatchedDhcpServerv4Reservation -ReferenceComputerName DHCP-Server-1 -DifferenceComputerName DHCP-Server-2 -ScopeId (((Get-DhcpServerv4Scope -ComputerName DHCP-Server-1 | 
Select-Object -ExpandProperty scopeId).ipAddressToString)) | 
ForEach-Object { Add-DhcpServerv4Reservation -ScopeId $_.ScopeId -ComputerName $_.MissingOnComputer -IPAddress $_.IPAddress -ClientId $_.ClientId -Description $_.Description -Name $_.Name -Type $_.Type -WhatIf }

Setting AD permissions for GALSync through Microsoft Identity Manager

A quick function for setting permissions in Active Directory to allow the Microsoft Identity Manager Global Address List (GAL) sync Management Agent to do its thing. I put it in a GitHub gist so it might help someone else!

It’s also a good intro to look at for getting into dealing with Access Control Lists (ACLs) in AD, as it deals with setting specific permissions or extended rights. Anyways, here’s the script!

System Center Endpoint Protection – Updated ADMX Template for the March 2016 Update – KB3106514

The new update has been out for a little while now (KB3106514) and brings with it three new settings.

HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Microsoft Antimalware\MpEngine
DWORD name: MpEnablePUS

This setting enables detection and removal of Potentially Unwanted Applications (PUA) downloaded through IE, Firefox or Chrome. One thing about this is that it will only apply to new detections going forward. This setting will not cause existing PUAs to be detected and removed.

HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Microsoft Antimalware\UX Configuration

DWORD name: SuppressRebootNotification

This is a setting to suppress the reboot notification from the client if it detects that a reboot is required to finish the clean-up of any malware. This is useful in shared environments (RDS, etc.), where a this kind of thing would not be fun.

HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Microsoft Antimalware

DWORD name: ThreatFileHashLogging

This setting records an event with ID 1120 to the log file containing the SHA-1 hash of the affected file for more research and correlation with other infections or threats.

There’s also a link from the knowledge base page to a script on the PowerShell gallery for setting up anti-malware client updates on a UNC share, which is quite nice for new deployments, without using something like System Center Configuration Manager (SCCM) or Windows Server Update Services (WSUS).

I have added these updates to my ADMX template for System Center Endpoint Protection, which can be downloaded from GitHub. Note that from this update on, the file names and data drop the 2012R2 version number from the file name, which makes more sense going forward. The old files are still there for reference.

The direct links to the files are:

SystemCenterEndpointProtection.admx
SystemCenterEndpointProtection.adml

It’s been just over a year since the last policy template settings change from Microsoft for their Endpoint Protection products and still no sign of an official file! I’ll keep on with the updates for this until Microsoft sort it out.

UPDATE:

I’ve made a couple more changes to add two new policy options that I had previously overlooked, these are:

HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Microsoft Antimalware\Real-Time Protection

DWORD name: DisableScriptScanning

This setting provides an admin override to disable script scanning.

HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Microsoft Antimalware\Real-Time Protection

DWORD name: LocalSettingOverrideDisableScriptScanning

This setting allows the local client setting for script scanning to take precedence over a group policy setting.

PowerShell – Timezone Module (PSGallery)

Today, I published my first module to the PowerShell gallery!

It’s the fairly simple module I wrote to manage the timezone on the local machine, wrapping the tzutil command. It’s all really come together over the last couple of days (I  fixed a bunch of problems by writing some proper tests for it!). I’ve also been using it to work with a lot of cool stuff with it like advanced parameter completion, psake and PSDeploy to streamline the testing and deployment.

Some of these ideas came from things I saw recently on the PowerShell.org Global Summit videos (They are all incredible). I’m annoyed I couldn’t make it this time,  but the videos and the other awesome stuff people are doing with PowerShell getting out there is great!

If bad things happen to good people, we must be the best.