Error 0x80070193 – Automatic Deployment Rules Software Updates (ADR) SCCM

So the other day… I was setting up one of my clients Automatic Deployment Rules (ADR) for SCEP Definition Updates. Everything went fine until I went to run the rule and I saw “HttpSendRequest failed HTTP_STATUS_FORBIDDEN or HTTP_STATUS_DENIED” followed by “ERROR: DownloadContentFiles() failed with hr=0x80070193” in the PatchDownloader.Log file.

PatchDownloader.Log error 80070193
ERROR: DownloadContentFiles() failed with hr=0x80070193

This was a shock as this error usually only occurs when the traffic is blocked by a proxy server and at this customer site I was told to bypass the proxy using DNS host targeting.

After some trial and error it dawned on me. The System account of the machine must still be pointing to the clients proxy or using a PAC file. So I grabbed my trusty tool PSEXEC and spawned a CMD as System using a CMD as Administrator and the command: “PSEXEC.EXE -I -S CMD”

psexec_systemcmd
PSEXEC to launch CMD as “System”

After this I navigated to “c:\Program Files (x86)\Internet Explorer” and launched “Iexplore.exe”.

Run Internet Explorer as System
Run Internet Explorer as System

Then I navigated in IE to Tools, Internet Options and finally LAN Settings, and her presto there it was, it was grabbing a PAC file!

Automatically detect settings selected.
Automatically detect settings selected.

So I checked if I could browse to MSN and sure enough I was blocked.

With Automatically detect Settings enabled
With Automatically detect Settings enabled

So I unticked the box, restarted IE from the System CMD and tried again…  MSN! First time I think I had ever been happy to see that laggy page!

Without Automatically detect settings enabled.
Without Automatically detect settings enabled.

Jumped back into ConfigMgr (SCCM) and ran my ADR rule to find all definitions downloading successfully. Hope that’s helps someone out!

Successfully downloading definition patches!
Successfully downloading definition patches!

 

 

.Net 4 Downgrade PowerShell Script

Recently I re-captured a clients Windows 7 Gold image and published it out in there Production Windows 7 OSD Task Sequence. This was all fine for a month or 2 until a machine using the software “Information at Work” needed to be rebuilt by their Service Desk as there were issues.

The problem was that Information at Work required .Net 4.5.* and no other version. This it seems must have been coded into the installer and the application.  VERY frustrating…

So I had to create a script to downgrade it for Windows 7 Clients and here it is.

[code language=”powershell”]

#Commented due to PS version 5 only — $Release = Get-ItemPropertyValue -Name Release -Path "HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full"

##Create Detection key function for ConfigMgr
$Unique = "InfoAtWork"
$DetectKey = "HKLM:\SOFTWARE\SOJ\SCRIPTS\$Unique"
function set-detectionKeys()
{
New-Item -Path HKLM:\SOFTWARE\ -Name SOJ –Force
New-Item -Path HKLM:\SOFTWARE\SOJ -Name SCRIPTS –Force
New-Item -Path HKLM:\SOFTWARE\SOJ\SCRIPTS -Name $Unique –Force

}

##Get .Net Version from Registry and hold it in variable $Release
$Key = ‘HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full’

If (Test-Path $Key)
{

$Release = (Get-ItemProperty -Path $Key -Name Release).Release

##Check Release version is 4.5
if ($Release -eq 378389)

{
set-detectionKeys
Set-ItemProperty -Path $DetectKey -Name NetVersion -Value $Release -Force
Write-Host "Correct Version Found Exiting"
Exit 0
}
##If it is not 4.5 uninstall and reinstall 4.5

Else
{
##Get all applications installed
$InstalledProducts = Get-WmiObject -Namespace ‘root\cimv2\sms’ -Class SMS_InstalledSoftware
#Filter out .Net
$DotNet = $InstalledProducts | where { $_.ARPDisplayName -imatch ‘NET Framework 4’ }
#Get uninstall string
#$Uninstall = $DotNet.UninstallString
$CachedMSI = $DotNet.LocalPackage
#Uninstall Dot Net
$Passthru = Start-Process ‘msiexec.exe’ -ArgumentList "/x $CachedMSI /qb /L*v $env:windir\temp\DotNetRelease$Release.log /norestart" -Wait -NoNewWindow
$Exitcode = [string]$Passthru.ExitCode

if($Exitcode -eq 0 -Or 3010)
{
#Write successfuly removal to the registry
set-detectionKeys
Set-ItemProperty -Path $DetectKey -Name Removed -Value $Release -Force
#Install .Net 4.5.1
Start-Process "$PSScriptroot\SetupNet451.exe" -ArgumentList "/q /norestart /ChainingPackage ADMINDEPLOYMENT" -Wait -NoNewWindow
#Set Detection Keys
$ReleaseInst = (Get-ItemProperty -Path $Key -Name Release).Release
set-detectionKeys
Set-ItemProperty -Path $DetectKey -Name Installed451 -Value $ReleaseInst -Force
#Tell ConfigMgr to Reboot
Exit 3010
}
Else
{
set-detectionKeys
Set-ItemProperty -Path $DetectKey -Name FailedRemoval -Value "ExitCode: $Exitcode" -Force
Exit 9999

}
}

}
Else
{
#Write not found and install 4.5.1
#set-detectionKeys
#Set-ItemProperty -Path $DetectKey -Name DotNet4 -Value ‘NotFound Installing 451’ -Force
#Install .Net 4.5.1
Start-Process "$PSScriptroot\SetupNet451.exe" -ArgumentList "/q /norestart /ChainingPackage ADMINDEPLOYMENT" -Wait -NoNewWindow
#Set Detection Keys
$ReleaseInst = (Get-ItemProperty -Path $Key -Name Release).Release
set-detectionKeys
Set-ItemProperty -Path $DetectKey -Name Installed451 -Value $ReleaseInst -Force
#Tell ConfigMgr to Reboot
Exit 3010

}

[/code]

  • First I create the function to create the detection keys in the registry.
  • Then I test the version of the .Net client installed in the registry by using this version information chart from Microsoft.
  • If it matches, happy days if it doesn’t match… find the uninstall string, create it and remove it (if its not found at all.. then jump to line 74 and install a fresh copy).
  • Check exit code “0” being success and “3010” being reboot, else fail the script and write to registry.
  • Re-install .Net 4.5.1 from the directory of the script, set detection keys and then tell the ConfigMgr client to reboot the device gracefully.

This I deployed using a Task Sequence as the “Information at Work” Software is deployed in that way. Also note that this will only work on Windows 7, so you might want to set a requirement on your application or task sequence step for “All Windows 7” Only.

If you need help creating the command line to run this as an application or task sequence CMD line check out this post.

Persist all Drivers at Sysprep stage

Ok, So I was capturing a very specific build for a government Audiology department the other day and needed to keep all drivers in the image as there were Hearing Aid and Hearing measurement devices that would need to be operated from these machines.

To do this is quite simple actually, just make sure BEFORE you kick off sysprep, whether that’s through SCCM, MDT or manually that you change these registry keys.

Navigate to:

HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\Sysprep\Settings\sppnp

Keep drivers during sysprep phase.

And then set:

  • PersistAllDeviceInstalls to 1 – This will keep all drivers for hardware that is connected to the machine at the time of sysprep.
  • DoNotCleanUpNonPresentDevices to 1 – This coupled with the above will addtionally keep all drivers for hardware that are not connected to the machine at the time of sysprep.

Note…

If you are using an answer file for sysprep configure your answer file to persist the drivers by adding the PersistAllDeviceInstalls setting in the Microsoft-Windows-PnPSysprep and giving it a value of true.

Remotely Start a Service with a list of Machines

So the other day I was on client site dealing with WES 2009 HP t510 thin clients. Now if anyone has ever dealt with WES 2009 and ConfigMgr (SCCM) then you will know it can be challenging.

Anyway the clients on the machines were failing the client check, this was because the Task Scheduler Service is not started by default in WES 2009. The Client Health check that the SCCM client performs on itself is started from a scheduled task, if that service is not started… Well there is your problem.

I needed a way to start that service on all the clients now without deploying to them as there was a write filter enabled or making a GPO change and rebooting them as users were working and on top, the next Maintenance Window was not for about 8 hours. So I came up with this very simple but highly effective for each loop. Firstly I wanted to double check they were all stopped so..

[code language=”powershell”]
foreach ($Machine in get-content c:\temp\Machines.txt) {cmd /c SC \\$Machine query Schedule}
[/code]

The text file must have a machine name per line and I’m sure you’ve noticed I’m using a CMD instead of PowerShell.. WES 2009 need I say more?

Once I was satisfied I changed one switch and hey presto it fired off the start command there and then to each machine.

[code language=”powershell”]
foreach ($Machine in get-content c:\temp\Machines.txt) {cmd /c SC \\$Machine start Schedule}
[/code]

For those who are not looking at WES 2009 here is the PowerShell command.

[code language=”powershell”]
foreach ($Machine in get-content c:\temp\Machines.txt) {
Get-Service -Name "Task Scheduler" -ComputerName $Machine | Set-Service -Status Running
}
[/code]

I did also change the GPO to auto start the service on the next reboot so I would never have to do it again 🙂

 

Copyright 2016 SCCMOG | All Rights Reserved