UMN OSD Front End Open Source First Release


We’ve built an OSD front end that works well for our uses and may serve other parts of the SCCM community as well. There are some features that we would like to implement which are currently missing such as setting a bind location but this isn’t something we currently do in our task sequences and so it wasn’t an immediate priority. The front end is broken down into five tabs pre-flight, computer name, backup options, user profiles, and applications.


Example pre-flight checks from a re-image task sequence.

We have built into the front end logic for a few different types of checks so far:

  • Physical Disk Count
    • You determine how many disks can be detected and then as long as the number of physical disks is below that number it will return a pass.
  • Ethernet Connection
    • Will check and pass if there is an active Ethernet connection.
  • Network Connectivity Check
    • Will check (by ping) if a network location is online and return a pass if it is. I’m using this to ping a storage appliance just to confirm basic connectivity but this could ping all sorts of things.
  • 64-Bit OS
    • Will check if the OS the front end is running on is 64-bit and then return a pass or fail based on if you’ve set the checkPassState to true (Pass if 64) or false (pass if not 64).
  • Offline Files Detected
    • This one is still in progress to some degree. Currently, if you use this check it’s going to go through the Win32_UserProfile and look for RoamingConfigured. I would like to expand on this more but this was a short term check just to see how useful this would be in our environment.

Computer Name

Example computer name tab.

The computer name tab is just a simple computer naming script essentially with some added checks on minimum and maximum length as well as starting and ending strings. All of these settings can be configured in the AppSettings.json file. You can also require or not require the various checks which will enable/disable the next button until the conditions are met.

Backup Options

Backup options we use in our task sequence. Right now these are hard coded in but can/should be made more flexible in future versions of the tool.

WE only leverage two backup options and as of right now I’ve hard coded these into the form. We have a USMT option as well as a full disk backup to a WIM file. Both of these options set an OSD Variable:

  • Wim backups set the OSDWIMBackup to True or False depending on checked state.
  • USMT backups set the OSDUSMTBackup to True or False depending on checked state.

If you’re not planning on implementing these I would disable this tab. A future version will include further options to customize this tab and possibly additional features if they’re requested for our own internal task sequence.

User Profiles

Example of the user profiles tab with a profile selected in the box but the name has been blocked out.

The user profiles tab was created when we started to do full disk images as backups during a re-image scenario. We wanted to cut down on the size of the images as much as possible and so removing profiles was the best option. You’ll find that this interface will show every profile (excluding the logged on user) and you can select as many profiles as you like. Clicking the set profiles for deletion button will set a variable in the application that upon completion of the form will do the profile removals. This cadence was done because we experienced long delay’s when trying to remove user profiles at this stage and it was a better user experience to move the deletion to the end of the form.


Example of applications list.

Now we come to my favorite tab. It was very much inspired by the SCConfigMgr OSD FrontEnd which we would likely have used internally had we been able to open the source code and make minor modifications to fit our needs. I would very much encourage everyone to check out their front end as it’s more feature complete than ours and may be a better solution depending on your needs.

Like their front end I’m using their web service to connect with SCCM and pull application names out of SCCM based on pre-applied administrative categories and then the checked applications are installed during a dynamic application install step.

Step in task sequence to install applications.

The list can grow quite large but we’ve had reasonably good success with this even installing large numbers of big applications. Cadence could be an issue but we haven’t encountered that so far either.

As you finish tabs they should be enabled and allow you to go back and re-do sections if needed. Once complete you just hit the complete button and it does everything it needs to do. If you exit the app using the close window button it will exit in error with code 22.

Generating a New SCCM Client GUID

  • Stop the SCCM service in Powershell using Stop-Service ccmexec and then wait for it to fully stop.
  • Rename the C:\Windows\SMSCFG.INI file to something like C:\Windows\SMSCFG.old.INI
  • Force the computer to update it’s AD certificate:
$certs = Get-Certificate -CertStoreLocation Cert:\LocalMachine\My -Template Machine
$thumbprint = $certs.Certificate.Thumbprint
certreq.exe -enroll -q -machine -cert "*$thumbprint*" Renew
  • Delete the computer object out of SCCM.
  • Restart the SCCM service using Start-Service ccmexec and then it should start up, generate a new GUID and re-create it’s object in SCCM with the new GUID.
  • Run Machine Policy Retreval & Evaluation Cycle in the SCCM client Control Panel.

Finding a Specific Setting in your Client Settings

With ConfigMgr 1806, the Application Catalog service and site roles are no longer needed, so for me it was a good opportunity to have 2 less servers to care and feed for. But because I was a dummy, in Default Client Settings I had selected my app catalog site explicitly rather than letting the client automatically pick (I have no idea why I did this). And when you make a new client setting, it inherits the settings of the default, so anyone who made a custom policy with Computer Agent had that setting. This setting being defined prevents the removal of the application catalog roles.

I have 41 Client Settings, I’m not about to look through each of them for Computer Agent settings. So Powershell to the rescue. Get-CMClientSetting will get you a list of all your Client Settings, but there won’t be any information on them. There’s a -Setting which will return all the settings of the specified type, but as it turns out, nothing to tell you which Client Setting contains that setting. So it turns out, you have to get every Client Setting, and interrogate it if it has the Computer Agent setting. With this code I was able to find the five Settings that had Computer Agent specified, and change the Default Application Catalog website point.

$allsettings = Get-CMClientSetting | select -ExpandProperty Name
foreach ($name in $allsettings) {
    if (Get-CMClientSetting -Setting ComputerAgent -Name $name) {
        write-host $name

I could have gone farther with this, as the object returned will have a PortalURL property, but merely listing the Settings that had Computer Agent was sufficient for this. This could be generalized to look for any Client Setting with a particular setting, and further to look for specific values if needed.

RBA and New Boot Media

This is a pretty simple one, but I love when solutions to problem I’m having with ConfigMgr Current Branch are the same (and thus the same solutions) as people using ConfigMgr 2007 (this seems to be a recurring trend with me).

I was creating new boot media using the New-CMBootableMedia cmdlet, and getting this error message:

New-CMBootableMedia : Create media exited with an error: -2147217407 (0x80041001)

If I tried to use the console I got this error:

Media creation failed with error code -2147217407.

Refer to CreateTsMedia.log file to find more details.

Checking CreateTsMedia.log (this file is created on the system where you’re creating the media from, at something like C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\AdminUILog\CreateTsMedia.log) I see this block of red text:

Staging certificate

Error invoking WMI method SMS_Site.SubmitRegistrationRecord (0x80041001)

StageCertificate::Register() failed. 0x80041001

Error executing state StageCertificate

Error executing first single pass

Failed to create media (0x80041001)

CreateTsMedia failed with error 0x80041001, details=''

CMtrace helpfully informs me that 0x80041001 is Generic Error, so things aren’t looking good.  After some Googling I come across someone with what sounds like the same error as me, except they’re having it with 2007, not 2012/CB.  But they did have a solution

My problem has been solved.  The SMS Admins group did not have “Import computer entry” and “Manager OSD and ISV Proxy Certificates” rights.

Well crap, the 2007/2012 permissions model is completely different, but I am running this as an account that doesn’t have the Full Administrator role, so let’s see what we can find.  I already had the “Import Computers” permission, under the Site node, but right below also in the Site node it was “Manage Certificates for Operating System Deployment” set to No.  Switch that to yes and give it another try, the boot media is successfully created!

Certificates would appear to be “scopeless” here.  Normally something at a system level without a scope belongs to the Default scope, but my account doesn’t have any roles applied to the Default scope, so it would appear that granting that permission is sufficient regardless of what scope the role is applied to.

Fixing the PowerON – PowerBI SCCM Current Branch 1806 Dashboard Queries

In our environment we’re seeing failures on some of the queries because we have multiple devices coming back when there should only be a single record.  I’ve created a gist with the updated SQL queries all you have to do is open up the corresponding queries and editing the root query running in SCCM.  Let me know if you find any additional edge cases where there could be potential fixes needed.

Wim Update Automation – ConfigMgr

Our desktop support folks were looking to keep their Wims up to date for their desktop OSD, and our server folks tagged along for the ride. Of course we went ahead and automated the entire process.

We leverage all of the previous works of OSD Gurus to build a MDT based CTGlobal Image Factory. Those posts are all well covered – go forth and seek out the deploymentBunny (aka:Mikael Nystrom); Kent Agerlund; Ami Arwidmark; Johan Arwidmark, and so on – these are well covered and not repeated here.

The next step is to build even more automation around this. The full workflow is as follows…

  1. Azure Automation Scheduled Task triggers runbook monthly to kick it all off
  2. Clean up any existing test VMs in my test cluster… decommission the old tests
  3. Create multiple local running processes on the ImageFactory server
    1. One each to build the local VM
    2. One each to monitor for completion
  4. The completion monitor kicks off new runbooks via webhooks when complete
  5. Refresh OSImage Package properties + Refresh package source.
  6. Check status then deploy VM (ours are in VMWare) specifying test TS
  7. Last package in the test TS is a powerShell script that calls… another runbook
  8. Unit testing – for lack of a better term of the test VM with shiny new OS
    1. Verify .Net version is latest.
    2. Windows update verification against Microsoft Catalog per OS
    3. powerShell / WMF Version verification
    4. SMBv1 / IIS / WCF Frameworks is disabled checks
    5. Insert check of your own 🙂
  9. If all unit tests pass – refresh Prod OSImage Package properties and source


To start with, gather all the MDT Task Sequence Ids from ImageFactory, the Operating Package ID from ConfigMgr, and some sort of unique identifier. I simply picked the OS Level being automated. Along with this… it does assume that you have managed to automate server VM builds in your environment.

## Servers to rebuild
$osList = @("2012","2016","2016-Core")

$oslist | ForEach-Object{
    $os = $_

    if ($os -eq '2012')
        $taskID = 'Server2012'
        $osID = 'ABC0000E'
        $deployOS = '2012R2'
    elseif ($os -eq '2016')
        $taskID = 'Server2016'
        $osID = 'ABC00012'
        $deployOS = '2016'
    elseif ($os -eq '2016-Core')
        $taskID = 'Server2016-Core'
        $osID = 'ABC00010'
        $deployOS = '2016-Core'

C:\Automation\ServerDecom.ps1 -computer $computer -rebuild $True

Quick note on the decommissioning part. My automation will flag for a rebuild system. What it does is instead of deleting the AD Computer object – it will instead reset the password. This is very important later on when the newly deployed test VM has a new IP address, and needs to dynamically update AD DNS. If you delete the computer object… say good bye to your computer’s access to update any existing DNS Records.

$sam = $computer+'$'
$password = ConvertTo-SecureString -String $sam -AsPlainText -Force
Get-ADComputer $sam -Credential $adCreds| Set-ADAccountPassword -NewPassword:$password -Reset:$true -Credential $adCreds

Moving on – the runbook still needs to kick off the MDT build. This takes a little prep work to have some local powerShell scripts saved on the Image Factory Server. The reason for doing this all is to keep from having a runbook run for excessive amounts of time waiting for the MDT build to complete.

Invoke-Command -ComputerName 'ImageFactory Server' -Credential $adCreds -ScriptBlock {
$process = "powershell.exe -file c:\scripts\$deployOS`.ps1"
$process2 = "powershell.exe -file c:\scripts\Monitor-$deployOS`.ps1"
} -ArgumentList $deployOS

The reason this was done with process creation is that the remote powerShell session will end all processes on exit. However, if you kick off new process inside the remote session – they stay running as system.

The two scripts that do the local heavy lifting…
Build VM

Remove-Module CTImageFactory -ErrorAction SilentlyContinue
Import-Module "e:\ImgFactory\Scripts\CTImageFactory.psm1" -WarningAction SilentlyContinue
set-location "e:\ImgFactory\Scripts\"
Start-Build -BuildType 'Single' -TaskSequenceID 'Server2016'

Monitor VM

Start-Sleep -Seconds 1200
$state = (Get-VM |where name -eq 'Server2016').State
until ($state -eq 'Off')

Invoke-RestMethod -Method Post -Uri '' -Body (ConvertTo-Json -InputObject @{'osID'='ABC00010';'computer'='Test Server Name';'deployOS'='2016-Core'}) -ErrorAction Stop

The last bit calls the next runbook via webhook in the gravy train. This is where it needs to check in with the site server, and make sure the newly captured wim files are updated and distributed. Then move on to deploy the wim as a test for verification.

$siteCode = Get-AutomationVariable -Name 'ConfigMgr-SiteCode'
$siteServer = Get-AutomationVariable -Name 'ConfigMgr-SiteServer'

################### Update wim file
$imageProperties = Get-WmiObject -ComputerName $siteServer  -Namespace "root/SMS/site_$sitecode" -Class 'SMS_ImagePackage' -Credential $sccmServiceAccount |where-object -property PackageID -eq $osID

Import-Module "C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1" -Force
$drive = get-psdrive -name MPT -ErrorAction SilentlyContinue
If(!$drive){New-psdrive -Name $siteCode -PSProvider "AdminUI.PS.Provider\CMSite" -root $siteServer -Credential $sccmServiceAccount  -Description "SCCM Site"}
$location = $siteCode+":"
Set-location $location
$date = get-date -format d
Set-CMOperatingSystemImage -Id $osID -Description $date -version "I'm NEW and Shiny'"
Remove-Psdrive MPT

# Check on status of distribution
$count = 0
Start-Sleep -Seconds 120
$status = Get-WmiObject -Credential $sccmServiceAccount -Namespace root\sms\site_$siteCode -Query "SELECT PackageID,PackageType,State,ServerNALPath,LastCopied FROM SMS_PackageStatusDistPointsSummarizer where PackageID = '$($osID)'" -ComputerName $siteServer | select-object PackageID,PackageType,State,LastCopied,ServerNALPath
if(($status.State | Where-Object {$_ -eq 0}).count -gt 1){$complete = $true}
}until($complete -or $count -eq 10)
if(-not($complete)){throw "SCCM Package failed to update in time"}    

Phew! All that to update content, distribution, some descriptions, and check that its all where it needs to be. As long as it all completes – then I call our internal automated server build scripts. We use boot media attached to the VM to automatically call the appropriate task sequence. In addition, we set OSD TS Variables in a text file accessible from the OSD environment to quickly set all needed variables. No waiting for device membership collections and so forth.

The last step of the task sequence is to call.. you guessed it – another runbook via a webhook. This last step is all about verifying the final product. Does it have the latest updates? Did the MDT TS do everything I needed it to do? Lets find out. Also, this is where having clean AD DNS really comes into play.

$session = New-PSSession -ComputerName $computer -Credential $creds
$dotNetTest = Get-AutomationVariable -Name 'dotnetTest'

# Test for dotNet version
$dotNetValidation = Invoke-Command -Session $session -ScriptBlock {
$dotNetVersions = (Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -recurse | Get-ItemProperty -name Release -EA 0 |Where-Object { $_.PSChildName -eq 'Full'} |Select-Object Release).Release
If ($dotNetVersions -ge $dotNetTest) {$dotNetValidation = 'Pass'}
Else {$dotNetValidation = 'Failed'}
} -ArgumentList $dotNetTest

Test for Microsoft Update CU

$updateValidation = Invoke-Command -Session $session -ScriptBlock {
$date = get-date -Format yyyy-MM
$updateTest = "$date Cumulative Update" # Needs to match $date + Cumulative Update *
$2012updateTest1 = "$Date Preview of Monthly Quality Rollup for Windows Server 2012 R2"
$2012updateTest2 = "$Date Security Monthly Quality Rollup for Windows Server 2012 R2"
$catalogURI = ""
$hotfixList = Get-HotFix |Sort-Object -Property hotfixid
$list = $hotfixlist[($hotfixList.count -3)..($hotfixList.count)].HotfixID
$updateValidation = 'Failed'
$list |ForEach-Object {
    $KB = $_
    $uri = $catalogURI + $kb
    try {
        # have to usebaseicparsing and the raw content as IE has not run yet
        $site = Invoke-WebRequest -Uri $uri -UseBasicParsing
        $content = $site.RawContent
        If ($content -like "*$updateTest*") {$updateValidation = 'Pass'}
        ElseIf ($content -like "*$2012updateTest1*") {$updateValidation = 'Pass'}
        ElseIf ($content -like "*$2012updateTest2*") {$updateValidation = 'Pass'}
    Catch {Write-Warning "Failed to lookup $KB"}

Getting into the rest of the validations — enter your own as needed

$powerShellValidation = Invoke-Command -Session $session -ScriptBlock {
    $powerShellVersion = '5.1'
    [string]$major = $PSVersionTable.psversion.major 
    [string]$minor = $PSVersionTable.psversion.minor
    $powerShellTest = $major + ".$minor"

    If ($powerShellTest -eq $powerShellVersion) {$powerShellValidation = 'Pass'}
    Else {$powerShellValidation = 'Failed'}

$features = Invoke-Command -Session $session -ScriptBlock {Get-WindowsFeature | Where-Object -Property 'InstallState' -eq 'Installed'}
    $smbTest = $features | Where-Object -Property Name -eq 'FS-SMB1'
    If ($smbTest) {$smbValidation = 'Failed'}
    Else {$smbValidation = 'Pass'}

    $iisTest = $features | Where-Object -Property Name -like 'web*'
    If ($iisTest) {$iisValidation = 'Failed'}
    Else {$iisValidation = 'Pass'}

    $wcfTest = $features | Where-Object -Property Name -like 'NET-WCF-*'
    If ($wcfTest) {$wcfValidation = 'Failed'}
    Else {$wcfValidation = 'Pass'}

$testing = @{
netvalidation = $dotNetValidation;
updatevalidation = $updateValidation;
powershellvalidation = $powerShellValidation;
smbvalidation = $smbValidation;
iisvalidation = $iisValidation;
wcfvalidation = $wcfValidation

$testing | ForEach-Object {
    If ($_.values -ne 'Pass') {$nextStep = 'Email'}
    Else {$nextStep = 'UpdateProd'}

At this point, if anything did not pass… it simply emails our ticketing queue to notify what did not pass so we can go fix the MDT TS or what ever the case may be. Otherwise, it moves on and updates the production OS package the same as the test.

Woah… kind of a lot.

So you want to automate against ConfigMgr… do you?

Automation is great. It really is. I’m using Azure Automation Hybrid Runbook workers for just about everything these days which is a post on its own, but wanted to touch base on some key interactions with ConfigMgr.

First, the premise. The automation servers are all running server 2016 core. So… no ConfigMgr console. No first popup of the console to set site assignments with powerShell. Actually, no real good way to get some default goodness with ConfigMgr at all. For the remainder of the post – the examples will all be dealing with my automation around updating OS Image Files.

So clearly I just copy over the powerShell module files with the .dlls in order to work better with the site server remotely. The simple route is to copy over the bin path C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin — to the same location on your core server. This will at least get you access to the powerShell modules.

Simple… but this is really messy in an automated world. Important here is making a new-psdrive and providing your service account credentials for the task at hand. Many of the ConfigMgr cmdlets do not allow for a -credential switch to provide access in line.

Import-Module "C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1" -Force
$drive = get-psdrive -name $siteCode -ErrorAction SilentlyContinue
If(!$drive){New-psdrive -Name $siteCode -PSProvider "AdminUI.PS.Provider\CMSite" -root $siteServer -Credential $sccmServiceAccount  -Description "SCCM Site"}
$location = $siteCode+":"
Set-location $location
$date = get-date -format d
Set-CMOperatingSystemImage -Id $osID -Description $date -version "I'm a NEW and Shiny'"
Remove-Psdrive $siteCode

Alternatively, you could certainly create a powerShell session with credentials; and then invoke a script block to the session. Sure – this works, but it opens up requiring the allowance of powerShell remoting for your service account. Just something to consider if you’re comfortable putting all your automation in script blocks.

Now… into the rabbit hole. I don’t like having to copy about files from a console. What happens if something changes in the ConfigMgr site version that updates the powerShell cmdlets… and now which servers need this copied where? There are many other reasons to keep this stuff off my core infrastructure, but honestly – I just don’t want to have to think about it. Keep it simple. Keep it to powerShell.

So some other good options. Obviously, Cim/Wmi work well since so much of ConfigMgr is accessible via this channel. They are also going to work with providing credentials! So letting a service account handle a well scoped task isn’t that big of a hurdle. What the hurdle is, is that not all Wmi objects will have the appropriate methods to write data back to your site server.

# Reload the image properties before refreshing the package on the distribution points
$imageProperties = Get-WmiObject -ComputerName $siteServer  -Namespace "root/SMS/site_$sitecode" -Class 'SMS_ImagePackage' -Credential $sccmServiceAccount |where-object -property PackageID -eq $osID

While this was great to get the first task done of updating the files in the system… there was no way to update the description or version via the Wmi object. When you pipe through to get-member – the properties exist, but there is no put() method.

Option five. The bottom of the rabbit hole I went down is to connect directly to the SMS Provider using WMI. This requires creating a SWbemServices object. Say what? No need to explain.. Microsoft Docs Page thank you docsMsft!

I rewrote the VB sample in powerShell a while back, and did a pull request. So side note – if you see something, write something, pull request back!

$siteCode = ''
$siteServer = 'server.domain'

$credentials = Get-Credential
$username = $credentials.UserName

# The connector does not understand a PSCredential. The following command will pull your PSCredential password into a string.
$password = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($credentials.Password))

$NameSpace = "root\sms\site_$siteCode"
$SWbemLocator = New-Object -ComObject "WbemScripting.SWbemLocator"
$SWbemLocator.Security_.AuthenticationLevel = 6
$connection = $SWbemLocator.ConnectServer($siteServer,$Namespace,$username,$password)


With a connector in place, you can do something like below to update description/version and put()it back

$wim = $connection.Get("SMS_ImagePackage.PackageID='$osID'")
$wim.Properties_.Item("Version").value = $version
$wim.Properties_.Item("Description").value = $Description

Here is the short of it. I can still provide credentials to run as what ever service principal I need, and then I get the benefit of being able to do.. well anything I want since its a direct connection against the SMS Provider itself.

There you have it folks. A full repertoire of how to get things done when coding in an automated way against ConfigMgr. Pick you poison wisely, or just mix and match as needed.

Strong Cryptography – .NET + powerShell

I spend a lot of time using Invoke cmdlets in powerShell. Over the past year there has been a need to address how the Invoke-RestMethod and Invoke-WebRequest handle SSL/TLS connections as service providers and API endpoints drop older versions of SSL and TLS. The good news is that providers are finally dropping these insecure channels, and the bad news is that Microsoft applications still default to allowing them as a client.

A few things for consideration. Disabling TLS 1.0 and all of SSL is rather simple – a few Registry Keys and a reboot – and done.  See the end of the post for the SCHANNEL Reg Keys.

It came as a surprise to me then when the Security Providers Keys are set, and then I started to get connection failures with a ‘Underlying Connection has Failed’ — very common wording for a SSL/TLS handshake failure. Whats going on powerShell? Why are you failing me?

Turns out… its because of .NET. If you pop open a powerShell session you can run


   — you will likely get the following output. “Ssl, Tls”

Not good powerShell. I said Ssl is disabled, and why wouldn’t you handshake to something better? Turns out powerShell isn’t as smart as you would think. You have a couple of options.

First — in the worst case if you still need to use Ssl… please don’t… but if you must, you can set a powerShell session to use TLS only by setting 

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 

But please don’t do this as a work around in your scripting. Please get rid of what ever other Ssl requirements are preventing a global system change.

Second — you can tell your OS to set the .Net Framework to use Strong Cryptography! You would think you only need to do this for Wow6432Node as who runs powerShell as a 32 bit process… but even if you check your environment, and are running as a 64 bit process it will still read the 32 bit version of .Net framework settings. Set the following, reboot, and your .Net calls from powerShell for the ServicePointManager will default to Tls, Tls11, Tls12.

Set-ItemProperty -Path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord

Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord


 No more connections issues!


Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0]
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client]
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server]
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0]
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Client]
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Server]
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0]
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client]
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server]
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1]
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client]
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server]
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2]
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client]
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server]

Managing Multiple ConfigMgr Sites with Powershell

We’re in the middle of migrating from a single ConfigMgr site to having two separate sites for servers and desktops.  Along with test sites, that’s a lot of sites to manage!  When you’re running Powershell on a machine that is managed by a site, you can easily cd, set-location, or push-location to that site’s drive. But what if you want to manage a site different than what’s managing your machine?  You can open a powershell terminal or ISE session directly from the console, but that can be a hassle, and also won’t work for things not run interactively.  I’ve taken to putting this code at the top of all of my scripts.

Continue reading “Managing Multiple ConfigMgr Sites with Powershell”

CIS Server Hardening and ConfigMgr

I recently worked on hardening an ConfigMgr Environment, using the CIS Windows Server 2016 Hardening Benchmarks.  We’re a CIS member so I have access to the GPO template, so after reading through the benchmark document, I removed the few settings I knew I didn’t want.

After applying this policy to my site systems, clients were no longer showing activity in the console, and they’d lost their green check mark.  I traced the path of a hardware inventory from one client, and it was able to successfully send the inventory to the management point, but it still wasn’t updating in the console.  I cranked up logging on the management point, and looked in mpfdm.log.  The log was full of errors like this:

**ERROR: Cannot connect to the inbox source, sleep 30 seconds and try again.

Occasionally I also had this error:

CFileDispMgr::GetStagingLocation(\) failed with 0X80070057
Continue reading “CIS Server Hardening and ConfigMgr”