ConfigMgr_OfflineImageServicing error – cannot delete

I came across an issue where the Offline Servicing for an OS image failed, and I couldnt get it to re-run successfully.

After a lot of research I found these commands helped to fully resolve the issue.

Run PowerShell as admin, then

dism.exe /cleanup-wim


dism.exe /cleanup-mountpoints


dism /get-mountedwiminfo

change the path below to your appropriate path. The below is 1 line of code.

dism /unMount-Wim /MountDir:F:\ConfigMgr_OfflineImageServicing\ABC00288\ImageMountDir /discard

posieandfig.co.uk

Resume BitLocker remotely using PowerShell

We came across a few machines during an in-place upgrade to Windows 10 1809 that failed to resume BitLocker once the upgrade had occurred.

We needed to identify which machines were affected, and we needed to remotely Resume bitlocker on those machines.

Identifying the machines in SQL

I came up with this SQL query that identifies the machines were the C:\ bitlocker status wasnt enabled:

select distinct HWS.DriveLetter0, HWS.ProtectionStatus0, SYS.Netbios_Name0
from v_GS_ENCRYPTABLE_VOLUME HWS INNER JOIN v_R_System SYS on HWS.ResourceID = SYS.ResourceID
where HWS.DriveLetter0 = 'C:' and HWS.ProtectionStatus0 = '0'

Resuming Bitlocker Remotely using PowerShell

verify its the machine in question

dir \\LAPTOP123\c$\users

check that the BitLocker status is actually suspended

Manage-bde -status -cn LAPTOP123 C:

Resume BitLocker

manage-bde -on C: -cn LAPTOP123

Outlook 2016/2019 – Disable Shared Mailbox Caching

We have been experiencing a lot of issues recently with Shared Mailboxes in Outlook 2016 not staying up to date.  This can be resolved by configuring 2 Group Policy settings.

These settings still allow the primary user mailbox to be cached to improve performance, but the Shared Mailboxes work Online so do not cache and remain up to date all the time.

The 2 settings you need to configure are:

User Configuration/Policies/Administrative Templates/Microsoft Outlook 2016/Account Settings/Exchange/Cached Exchange Mode
Download shared non-mail folders – Disabled
User Configuration/Policies/Administrative Templates/Microsoft Outlook 2016/Outlook Options/Delegates
Disable shared mail folder caching – Enabled

SharedMailbox

Include Lenovo BIOS update in a task sequence

We are deploying Windows 10 Creators Upgrade package to our 1400 Windows 1511 laptops, but we noticed a bug related to usb functionality that a BIOS update resolves.  Having never included a BIOS update in a task sequence before, I started the challenge and spent literally days getting it to work.  Now I have the process working I thought I would share to save someone else some long days.

 

  1. I first downloaded the bios update from the Lenovo site and then extracted it locally onto my machine.

 

  1. Then I created a new package in SCCM containing those files, and chose not to create a new program when asked in the wizard; we’ll run everything from command line.

 

  1. I created a new step in the task sequence to create a directory on the laptop running the task sequence. My logic was that I can copy the bios files there from the temporary package content, and run the bios upgrade from the permanent files rather than risking SCCM removing the content before the laptop has applied the update.  This seemed to add some stability to the bios installation process, so I’d recommend you do the same.

Add a Run Command Line step called Make Bios Directory and use the command

cmd.exe /c md c:\bios

(choose another directory if you wish)

1

 

4.   The next step is a Group with a wmi filter specified. This determines what model of laptop can run which bios upgrade, in the case of our Yoga 260s the wmi filter is

SELECT * FROM Win32_ComputerSystem WHERE MODEL LIKE ‘%20FEA00FUK%’

2

 

5.   The next step is where the bios files are copied from the package cache to c:\bios. Ensure you select the package that the bios files are located in

This is completed using the Run Command Line, and the command used is

xcopy.exe “.\*.*” “C:\bios” /D /E /C /I /Q /H /R /Y /S

3

 

6.  The final step is to apply the bios upgrade, again I use another Run Command Line action. It’s very important to populate the Start in: field with the directory the bios files are located in.  This caused me hours and hours of frustration as none of the previous guides showed this as being necessary, but in my case it certainly was needed. The command needed is

C:\bios\WINUPTP.exe -s

and the Start In field is

C:\bios

4

Make sure your laptop has AC Power or else the bios upgrade won’t occur! (Another gotcha I came across.)

Ensure the Continue on error tickbox is ticked on this step as it usually returns an error even though its successful.  (Another gotcha I came across.)

Now test the task sequence and ensure it works.

 

Within the logs in sccm it shows this Upgrading Bios step as failed as it returns an error code of 1 instead of 0.  Once I was happy that it was working reliably on multiple machines I altered the Success codes to include a code of 1.  Nice white logs rather than red and orange!

5

I squeezed in a little bit of time at the end because Lenovo give an option to edit the logo on the bios screen.  I went ahead and added the version number so I can easily tell which machines have the correct bios.  The file needs to be created in the root of the extracted bios files named logo.bmp, it has to be a certain size etc but just read the documentation for details.

Hope this saves someone some time.

6

 

 

 

 

Writing Current User registry keys in SCCM as System

It is possible to write CurrentUser registry keys by deploying an application/package that runs as the System.  This could be useful when installing an application and wanting to set the personalisation registry keys for the logged in user at the same time.  The script I’ve used below also allows you to install it for all users on that machine, and also for the Default User so all future users get those settings.

 

You’ll need 3 things:

  1. A registry file that contains the settings you want to add.

1

  1. This script from TechNet https://gallery.technet.microsoft.com/scriptcenter/Write-to-HKCU-from-the-3eac1692

**this file looks to have been removed for some reason. I have included the script at the bottom of the page, just save it as WriteToHkcuFromsystem.ps1**

  1. A batch file similar to this.

It basically enables the powershell script to run, runs the script to add the registry key(s) for the Current User that is logged on, and then returns the powershell execution policy back to what it was.

2

PowerShell.exe Set-ExecutionPolicy -ExecutionPolicy Unrestricted

PowerShell.exe -File “%~dp0WriteToHkcuFromsystem.ps1” -RegFile “%~dp0DisableTaskBarThumbnails.reg” -CurrentUser

PowerShell.exe Set-ExecutionPolicy -ExecutionPolicy Restricted

 

I created a new package in SCCM containing the following files

3

 

Ensure that you choose “Only when a user is logged on”. This means it will be able to pick up the Current User and apply the registry settings to that user.

4

 

For the Command being run just choose the install.bat.   I made sure it runs hidden as well.

5

 

Deploy out to some test machines and you should find it populates the Current User hive of the registry.  Take a look at the script on TechNet as it shows how to add the registry key(s) to   -CurrentUser -AllUsers -DefaultProfile

WriteToHkcuFromsystem.ps1 contents

PARAM(

    [Parameter(Mandatory=$true)]
    [ValidatePattern('\.reg$')]
    [string]$RegFile,

    [switch]$CurrentUser,
    [switch]$AllUsers,
    [switch]$DefaultProfile
)


function Write-Registry {
    PARAM($RegFileContents)
    $tempFile = '{0}{1:yyyyMMddHHmmssff}.reg' -f [IO.Path]::GetTempPath(), (Get-Date)
    $RegFileContents | Out-File -FilePath $tempFile
    Write-Host ('Writing registry from file {0}' -f $tempFile)
    try { $p = Start-Process -FilePath C:\Windows\regedit.exe -ArgumentList "/s $tempFile" -PassThru -Wait } catch { }
    if($p -ne $null) { $exitCode = $p.ExitCode } else { $exitCode = 0 }
    if($exitCode -ne 0) {
        Write-Warning 'There was an error merging the reg file'
    } else {
        Remove-Item -Path $tempFile -Force -ErrorAction SilentlyContinue
    }
}

if(-not (Test-Path -Path $RegFile)) {
    Write-Warning "RegFile $RegFile doesn't exist. Operation aborted"
} else {

    if($CurrentUser -or $AllUsers -or $DefaultProfile) {

        Write-Host ('Reading the registry file {0}' -f $RegFile)
        $registryData = Get-Content -Path $RegFile -ReadCount 0

        if($CurrentUser) {
            Write-Host "Writing to the currenlty loggoed on user's registry"
            $explorers = Get-WmiObject -Namespace root\cimv2 -Class Win32_Process -Filter "Name='explorer.exe'"
            $explorers | ForEach-Object {
                $owner = $_.GetOwner()
                if($owner.ReturnValue -eq 0) {
                    $user = '{0}\{1}' -f $owner.Domain, $owner.User
                    $ntAccount = New-Object -TypeName System.Security.Principal.NTAccount($user)
                    $sid = $ntAccount.Translate([System.Security.Principal.SecurityIdentifier]).Value
                    $RegFileContents = $registryData -replace 'HKEY_CURRENT_USER', "HKEY_USERS\$sid"
                    Write-Registry -RegFileContents $RegFileContents
                }
            }
        }

        if($AllUsers) {
            Write-Host "Writing to every user's registry"
            $res = C:\Windows\system32\reg.exe query HKEY_USERS
            $res -notmatch 'S-1-5-18|S-1-5-19|S-1-5-20|DEFAULT|Classes' | ForEach-Object {
                if($_ -ne '') {
                    $sid = $_ -replace 'HKEY_USERS\\'
                    $RegFileContents = $registryData -replace 'HKEY_CURRENT_USER', "HKEY_USERS\$sid"
                    Write-Registry -RegFileContents $RegFileContents

                }
            }
        }

        if($DefaultProfile) {
            Write-Host "Writing to the default profile's registry (for future users)"
            C:\Windows\System32\reg.exe load 'HKU\DefaultUser' C:\Users\Default\NTUSER.DAT | Out-Null
            $RegFileContents = $registryData -replace 'HKEY_CURRENT_USER', 'HKEY_USERS\DefaultUser'
            Write-Registry -RegFileContents $RegFileContents
            C:\Windows\System32\reg.exe unload 'HKU\DefaultUser' | Out-Null
        }

    } else {
        Write-Warning 'No mode was selected. Operation aborted'
    }
}

Silent install of InfoPath 2013 standalone

We have updated our task sequence to deploy Office 2016 but InfoPath is not included in Office 2016. Microsoft provide a standalone version of Infopath for installation and the below are instructions on how to make that installation occur silently. note: I strongly advise you install Infopath 2013 first and then Office 2016 second. Doing it the other way around means InfoPath 2013 overwrites some Office 2016 settings.

 

  1. Download one of the InfoPath standalone packages from here
  1. Extract the files using one of the below command from an elevated command prompt

infopath_4753-1001_x64_en-us.exe /extract

or

infopath_4753-1001_x86_en-us.exe /extract

 

  1. In the newly extracted files, open Config.xml located within the “infopathr.ww” directory

11

  1. Modify the Config.xml file like this:

<Configuration Product=”Infopathr”>

<Display Level=”none” CompletionNotice=”no” SuppressModal=”yes” AcceptEula=”Yes” />

</Configuration>

22

  1. I now use a batch file to run the installation. The batch file should be located in the root of the newly extracted files (same level as setup.exe)

“%~dp0setup.exe” /config “%~dp0infopathr.ww\config.xml”

33

  1. The first time InfoPath is opened it may prompt for activated online. If this occurs add in the following line at the end of the batch file

 

cscript “C:\Program Files (x86)\Microsoft Office\Office15\ospp.vbs” /act

 

Update 2

I also came across an issue where old Office 2003 format documents with the .xml file format would not open, excelDoc.xml WordDoc.xml etc.  To fix this add these reg keys and this restores the functionality and also makes sure you dont have blank icons for those xml files. For anyone using the reg keys below know it took 25+ hours to identify them!

The top section allows .xml files to be determined by their content.

The second section stops Edge from trying to take over .xml file formats.

The third section stops a security prompt in Outlook when the files are opened from attachments.

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared\XML\ProgIds]
“InfoPath.Document”=””
“Excel.Sheet”=””
“PowerPoint.Show”=””
“Word.Document”=””

[HKEY_CLASSES_ROOT\AppXcc58vyzkbjbs4ky0mxrmxf8278rk9b3t]
“NoOpenWith”=””
“NoStaticDefaultVerb”=””

[HKEY_CLASSES_ROOT\xmlfile]
“EditFlags”=hex:00,00,01,00

 

 

unattended install InfoPath 2013 standalone Office 2013 Office 2016

Credits to Eddie Jackson http://eddiejackson.net/wp/?p=10954

Credits to Adam Fowler  https://www.adamfowlerit.com/2017/09/disabling-outlook-opening-mail-attachment-prompt/

Credits to Ramesh Srinivasan http://www.winhelponline.com/blog/edge-hijack-pdf-htm-associations/

 

 

Silent install of Adobe Flash v22 + forcing uninstallation of v10 + v11

We recently had a requirement to ensure all laptops were running the latest version v22 of Adobe Flash on our Windows 7 laptops, and a quick query in SCCM showed 95% were on version 21 which was good, but a number were stuck on version 10 and 11!  A lot of troubleshooting later and it turns out that the uninstall of these versions was the cause, as it was leaving behind some registry entries that caused the new version to fail installation.

 

After combining a few vbs scripts I came up with the following vbs script that removes the registry entries in order for the uninstall to complete, and the install to work.  If you need to alter it, locate the GUID  HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Installer\Products\xxx where xxx is the adobe flash installation. the sub keys will tell you whether it is or not.

removeRegTraces.vbs

'this script removes remnants of flash player from SOFTWARE\Classes\Installer\Products\ 
On Error Resume Next
Const HKEY_LOCAL_MACHINE = &H80000002

strComputer = "."

Set objRegistry = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")

'adobe flash 10.3.183.5
strKeyPath = "SOFTWARE\Classes\Installer\Products\C4DD4D27947025346BE3A7C7296834E0"
if KeyExists(HKEY_LOCAL_MACHINE, strKeyPath) = True then
   DeleteSubkeys HKEY_LOCAL_MACHINE, strKeypath 
end if

'adobe flash 11.0.1.152
strKeyPath = "SOFTWARE\Classes\Installer\Products\03797D32A1CEE534388FAABEEF25730B"
if KeyExists(HKEY_LOCAL_MACHINE, strKeyPath) = True then
   DeleteSubkeys HKEY_LOCAL_MACHINE, strKeypath 
end if

' adobe flash 16.0.0.305
strKeyPath = "SOFTWARE\Classes\Installer\Products\0418CB86AAF391446BEECC6FB06EAD2B"
if KeyExists(HKEY_LOCAL_MACHINE, strKeyPath) = True then
   DeleteSubkeys HKEY_LOCAL_MACHINE, strKeypath 
end if



Sub DeleteSubkeys(HKEY_LOCAL_MACHINE, strKeyPath) 
 objRegistry.EnumKey HKEY_LOCAL_MACHINE, strKeyPath, arrSubkeys 

 If IsArray(arrSubkeys) Then 
   For Each strSubkey In arrSubkeys 
   DeleteSubkeys HKEY_LOCAL_MACHINE, strKeyPath & "\" & strSubkey 
   Next 
 End If 

 objRegistry.DeleteKey HKEY_LOCAL_MACHINE, strKeyPath 
End Sub


Function KeyExists(Key, KeyPath)
 Dim oReg: Set oReg = GetObject("winmgmts:!root/default:StdRegProv")
   If oReg.EnumKey(Key, KeyPath, arrSubKeys) = 0 Then
     KeyExists = True
   Else
     KeyExists = False
   End If
End Function

Along with uninstall_flash_player.exe http://download.macromedia.com/get/flashplayer/current/support/uninstall_flash_player.exe

And an mms.cfg file to stop auto updates I managed to get it complete successfully, and now all 1000 windows 7 machines are upgrading fine 🙂

 

Here is the mms.cfg file contents

SilentAutoUpdateEnable=0
AutoUpdateDisable=1

 

And the batch file that is run that carries out all the above actions.

@echo off
"%~dp0uninstall_flash_player.exe" -uninstall
@call cscript "%~dp0removeRegTraces.vbs"
msiexec /i "%~dp0install_flash_player_22_active_x.msi" /qn
del /s c:\Windows\System32\Macromed\Flash\mms.cfg
copy /y "%~dp0mms.cfg" c:\Windows\System32\Macromed\Flash

 

upgrade folder contents

adobe upgrade

Stop network adapter going to sleep on Windows 10

We were experiencing issues with the wireless network adapter going to sleep when not in use, and wanted to make sure it stays awake all the time.

There is a tickbox on the network adapter that needed to be unticked on the wireless card and also the network port on the laptop. The setting is Allow the computer to turn off this device to save power. Rather than doing this manually every time a laptop is rebuilt I found a powershell script and modified it to suit our needs.

screenshot

This is the original script that disables power saving on all Intel network cards.

$nics = Get-WmiObject Win32_NetworkAdapter | where {$_.Name.Contains('Intel')}

foreach ($nic in $nics)
{
    $powerMgmt = Get-WmiObject MSPower_DeviceEnable -Namespace root\wmi | where {$_.InstanceName.Contains($nic.PNPDeviceID)}
    $powerMgmt.Enable = $False
    $powerMgmt.psbase.Put()
}

 

I altered it to suit our needs and now the powershell script runs and outputs a log file.  It searches for all 4 of the network adapters we want to change, makes sure it can disable Power Management on that network adapter, then checks if power management is enabled and if it is then it disables it.

$file = "C:\NICpowerChange.log"
"Searching for AX88772A / Thinkpad / Lenovo / Intel" | Add-Content -Path $file

#find relevant network adapters
$nics = Get-WmiObject Win32_NetworkAdapter | where {$_.Name.Contains('AX88772A') -or $_.Name.Contains('Thinkpad') -or $_.Name.Contains('Lenovo') -or $_.Name.Contains('Intel')}

$nicsFound = $nics.Count
"number of network adapters found: ", $nicsFound | Add-Content -Path $file

foreach ($nic in $nics)
{
   $powerMgmt = Get-WmiObject MSPower_DeviceEnable -Namespace root\wmi | where {$_.InstanceName -match [regex]::Escape($nic.PNPDeviceID)}
 
   # check to see if power management can be turned off
   if(Get-Member -inputobject $powerMgmt -name "Enable" -Membertype Properties){

     # check if powermanagement is enabled
     if ($powerMgmt.Enable -eq $True){
       $nic.Name, "----- Enabled method exists. PowerSaving is set to enabled, disabling..." | Add-Content -Path $file
       $powerMgmt.Enable = $False
       $powerMgmt.psbase.Put()
     }
     else
     {
       $nic.Name, "----- Enabled method exists. PowerSaving is already set to disabled. skipping..." | Add-Content -Path $file
     }
   }
   else
   {
     $nic.Name, "----- Enabled method doesnt exist, so PowerSaving cannot be set" | Add-Content -Path $file 
   }
}

Error installing OneDrive for Business Next Generation Sync Client

We wanted to install the latest and greatest OneDrive for Business Next Generation Sync Client in the hope it will fix the numerous support calls we receive about syncing issues from our staff.
We have the Office 2013 365 OneDrive for Business already installed but ran into a lot of trouble trying to the Next Gen client installed. We saw the following errors (amongst others) in the logs

!ERROR! (0x80070005) (fsmanagerimpl.cpp:470) ERROR: “” failed with 0x80070005 in .

LogsUploader: Unable to resolve upload host: 11001

ERROR: “” failed with 0x80040b01 in
After some searching around it seems a group policy was stopping it install. The group policy stops the personal version of OneDrive in our corporate environment but it seems this
was stopping the Next Generation client installing.

The policy is
Computer Configuration – Polices – Administrative Templates – Windows Components – OneDrive
“Prevent usage of onedrive for file storage” = Disabled

This was set to Enabled and was causing our errors.

To quickly prove this we tweaked the corresponding registry key located here: HKLM\Software\Policies\Microsoft\Windows\OneDrive – DisableFileSyncNGSC and set it to the value 0 (zero)

We also came across some registry settings that we used to customise the user experience of the new client.

HKEY_CURRENT_USER\SOFTWARE\Microsoft\OneDrive

Create a DWORD key with value name “DefaultToBusiness” with value data 1
Create a DWORD key with value name “EnableAddAccounts” with value data 1
Create a DWORD key with value name “DisablePersonalSync” with value data 1

 

Office 2003 .xml files – blank/white/missing icons

We’ve been having a lot of issues recently with legacy Office 2003 files saved as .xml on our new laptops running Windows 8.1 and Windows 10 with Office 2013 (365).  The issue has been that the icons for these files have all been blank/white icons instead of Excel/Word icons etc.

The files themselves are a mixture of Word, Excel and InfoPath files and although they open correctly when double clicked, its confusing a lot of our staff who are frequently calling for support. The incorrect icons we see are these below

incorrecticons

After a lot of investigation I have found that the Office365 version of the Office2013 installer has some registry keys missing.  Creating these keys and waiting 10-20 minutes brings the icons back to normal.  This was the case on our domain machines and on a newly built Windows non-domain machine with Office 2013 installed and up to date.

The registry keys to add are below. Save the text below* as a text file with .reg as the file extension and import into the registry.  *You may need to replace the quotation marks with normal ones in Notepad.

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared\XML]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared\XML\ProgIds]
“Word.Document”=””
“Excel.Sheet”=””
“PowerPoint.Show”=””
“InfoPath.Document”=””

Correct Icons

All is now working after importing the keys and waiting a while for windows to update the icon cache.  Even after manually clearing the icon cache the icons didn’t resolve themselves, just leave the machine turned on for 20 minutes and it worked seemed to figure it out in due course.

xmlfilesworking