Registry Keys for Windows 10 Application Privacy Settings

The following registry keys in this post control the privacy settings in Windows 10. These settings can be found in the GUI by going to SETTINGS\PRIVACY.
Read more

Change your Office 365 ProPlus Update Channel using SCCM

Office 365 ProPlus has four different update channels:

  • Monthly Channel (Targeted)
  • Monthly Channel
  • Semi-annual Channel (Targeted)
  • Semi-annual Channel

In order to switch your client to different channels, you must change the CDNBaseUrl and UpdateChannel registry keys in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\ClickToRun\Configuration. In the Set-Office365Channel function we will be using C:\Program Files\Common Files\Microsoft Shared\ClickToRun\OfficeC2RClient.exe to update the CDNBaseUrl key and we will be automatically setting the UpdateChannel key. We are updating the UpdateChannel key because in my testing, SCCM would not deploy the new update channel patches if you did not set this key. After these two tasks are complete, the function will run a hardware inventory scan so SCCM can update the channel in the console.

How to use Set-Office365Channel:

  • Switch to Monthly Channel (Targeted)
    Set-Office365Channel -UpdateChannel Insiders
  • Switch to Monthly Channel
    Set-Office365Channel -UpdateChannel Monthly
  • Switch to Semi-annual Channel (Targeted)
    Set-Office365Channel -UpdateChannel Targeted
  • Switch to Semi-annual Channel
    Set-Office365Channel -UpdateChannel Broad
Function Set-Office365Channel {


    .SYNOPSIS Change Office 365 Update Channel 

    .PARAMETER UpdateChannel Provide update channel that you would like to use 

    .EXAMPLE - Switch to Monthly Channel (Targeted) 
    Set-Office365Channel -UpdateChannel Insiders

    .EXAMPLE - Switch to Monthly Channel 
    Set-Office365Channel -UpdateChannel Monthly

    .EXAMPLE - Semi-annual Channel (Targeted) 
    Set-Office365Channel -UpdateChannel Targeted

    .EXAMPLE - Semi-annual Channel 
    Set-Office365Channel -UpdateChannel Broad


    param (
        # Provide update channel that you would like to use
        [ValidateSet('Insiders', 'Monthly', 'Targeted', 'Broad')]

    $Channel = Switch ($UpdateChannel) {

        "Insiders" {""}
        "Monthly" {""}
        "Targeted" {""}
        "Broad" {""}


    $Configuration = "HKLM:\SOFTWARE\Microsoft\Office\ClickToRun\Configuration"

    If((Get-ItemProperty $Configuration).CDNBaseUrl -ne "$Channel") {

        # Update Channel
        Start-Process "C:\Program Files\Common Files\Microsoft Shared\ClickToRun\OfficeC2RClient.exe" -ArgumentList "/changesetting Channel=$UpdateChannel"
        Set-ItemProperty "HKLM:\SOFTWARE\Microsoft\Office\ClickToRun\Configuration" -Name UpdateChannel -Value "$Channel" -Force

        # Trigger Hardware Inventory
        Invoke-WmiMethod -Namespace "root\ccm" -Class "SMS_Client" -Name "TriggerSchedule" -ArgumentList "{00000000-0000-0000-0000-000000000001}"



How to reset your start menu layout in Windows 10 1809

Well Microsoft has changed things again since my last post that showed you how to reset the start layout in Windows 10 1709. Now with 1809 there is a new key name and it does look to be slightly random so I am now having to use a wildcard. I’m currently only testing every other build so please keep me updated if this breaks with a spring feature upgrade release.

Remove-Item 'HKCU:\Software\Microsoft\Windows\CurrentVersion\CloudStore\Store\Cache\DefaultAccount\*$start.tilegrid$'  -Force -Recurse
Get-Process Explorer | Stop-Process

Are you trying to reset the start layout for Windows 10 1709? Click here to find out how.

How to install Office 365 ProPlus updates during your SCCM build and capture task sequence

Have you tried to install Office 365 ProPlus updates during your SCCM build and capture task sequence and it never installed? Well that is most likely due to a registry key that was not updated. The update channel registry key value in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\ClickToRun\Configuration should not be pointing to your ccmcache folder. If it is, then this fix will work for you.

In order to update this key, you should run the following command before the Install Updates step in your task sequence.:
“C:\Program Files\Common Files\Microsoft Shared\ClickToRun\OfficeC2RClient.exe” /update SCHEDULEDTASK displaylevel=False

Note: This command must run before you attempt to install any Office 365 ProPlus software updates in your task sequence. If it does not then your update channel value will still be pointing to the ccmcache which will stop the updates from running.

Find more information here:

SCCM script to identify systems vulnerable to ADV180028

You can run the following script against an SCCM collection to identify a system’s Bitlocker encryption method. This will help you find any computers that may be vulnerable to ADV180028.

Note: Your system may be vulnerable if your encryption method is set to Hardware Encryption!

$EncryptionMethod = manage-bde -status C: | Where-Object {$_ -match "Encryption Method"}

If ($EncryptionMethod -ne $Null) {

    $EncryptionMethod = $EncryptionMethod.Split(":")[1].trim()

Else {

    $EncryptionMethod = "Encryption Method not found"



Learn more about ADV180028 here.
Learn how to deploy scripts in SCCM here.

Get-LoggedOnUser Function

Use the Get-LoggedOnUser function to find out who is the current logged on user on a local or remote machine. The function can be useful for SCCM deployments or just trying to find out who is logged on a remote computer.

Find out who is logged on to a remote machine:
Get-LoggedOnUser -ComputerName COMPUTERNAME-D
Find out the current local logged on user:

Source Code:

Function Get-LoggedOnUser {

    Find out the current logged on user on a local or remote machine
    .PARAMETER ComputerName
    Provide remote computer name
    Get-LoggedOnUser -ComputerName COMPUTERNAME-D

    param (
    If($ComputerName -eq $Null) {

        $Username = (Get-Process Explorer -IncludeUsername | Where-Object { $_.Username -notlike "*SYSTEM" }).Username

    Else {

        $Username = (Invoke-Command {Get-Process Explorer -IncludeUsername | Where-Object { $_.Username -notlike "*SYSTEM" }} -ComputerName $ComputerName).Username


    Return $Username


How to disable Microsoft Teams from running at logon

If you landed on this page you are probablly working on packaging Microsoft Teams and have been banging your head against a desk trying to figure out how to disable it from loading at startup. Fortunately for you, I figured out a solution that works 100% of the time.

What do you need?
Microsoft Teams

Where to download?
Node.JS –
Microsoft Teams –
Notepad++ –

Brief background
Essentially, Microsoft Teams is a webpage in the background. It was developed with Electron which is a framework that lets developers create cross-platform desktop apps with web front-end technologies. Some other popular applications such as Skype, and Visual Studio Code were also built with using this technology.

With Electron apps, most of the source files for the application will be packaged into a file named app.asar. You can open the file in Notepad but you cannot save it since it is a READONLY file. From my experience, any changes made to it via Notepad will crash the app and prevent it from loading.

How do you do it?

  1. Download and install Microsoft Teams
  2. Download and install Node.JS
  3. Open the CMD prompt as an Administrator
  4. Run: npm install -g asar
  5. Run: asar extract "%LOCALAPPDATA%\Microsoft\Teams\current\resources\app.asar" C:\Temp\asar
    Note – Try running “C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Node.js\Node.js command prompt.lnk” if the command prompt does not recognize the ASAR command.
  6. Navigate to C:\Temp\asar\lib
  7. Locate desktopConfigurationManager.js and open the file with Notepad++
  8. Search for OPENATLOGIN (There should be two references) and set the value to FALSE as shown below in the screenshots:
    disable teams at startup
    disable teams at startupli>

    Last but not least, it is time to repackage everything!

  9. Run: asar pack "C:\TEMP\asar" "C:\TEMP\app.asar" --unpack *.node

Now that you have a customized app.asar, you can silently install Teams and also not worry about it launching at startup. See the install script below for an example:

# Install Microsoft Teams
Start-Process "$PSScriptRoot\Teams_windows_x64.exe" -ArgumentList "-s" -Wait

# Copy customized app.asar
Copy "$PSScriptRoot\app.asar" "$env:LOCALAPPDATA\Microsoft\Teams\current\resources\app.asar" -Force

Validate-GroupMembership Powershell Function

Use the Validate-GroupMembership function to confirm whether or not a user or computer object is a member of an AD group.

Find out if the current user is a member of an AD group called “Test Group”
Validate-GroupMembership -SearchString $env:USERNAME -SearchType User -Group “Test Group”

Find out if the current computer is a member of an AD group called “ORL Computers”
Validate-GroupMembership -SearchString $env:COMPUTERNAME -SearchType Computer -Group “ORL Computers”

Function Validate-GroupMembership {


    Validates AD group membership for a user or computer object
    .PARAMETER SearchString
    Provide Username or Computer Name
    .PARAMETER SearchType
    Specify type (User or Computer)

    .PARAMETER Group
    Provide AD Group name
    Validate-GroupMembership -SearchString $env:USERNAME -SearchType User -Group "Test Group"
    Validate-GroupMembership -SearchString $env:COMPUTERNAME -SearchType Computer -Group "ORL Computers"


    param (
     [ValidateSet("User", "Computer")]

    Try {

        $objSearcher = New-Object System.DirectoryServices.DirectorySearcher
        $objSearcher.SearchRoot = New-Object System.DirectoryServices.DirectoryEntry

        If ($SearchType -eq "User") {

            $objSearcher.Filter = "(&(objectCategory=User)(SAMAccountName=$SearchString))"

        Else {

            $objSearcher.Filter = "(&(objectCategory=Computer)(cn=$SearchString))"


        $objSearcher.SearchScope = "Subtree"
        $obj = $objSearcher.FindOne()
        $User = $obj.Properties["distinguishedname"]

        $objSearcher.Filter = "(&(objectClass=group)(cn=$Group))"
        $obj = $objSearcher.FindOne()

        [String[]]$Members = $obj.Properties["member"]

        If($Members.count -eq 0) {                       

            $rangeBottom =0
            $rangeTop= 0

            While (! $retrievedAllMembers) {

                $rangeTop=$rangeBottom + 1499               




                Try {

                    $obj = $objSearcher.FindOne() 
                    $rangedProperty = $obj.Properties.PropertyNames -like "member;range=*"
                    $Members +=$obj.Properties.item($rangedProperty)          
                        if ($Members.count -eq 0) { $retrievedAllMembers=$true }

                Catch {




    Catch {

        Write-Host "Either group or user does not exist"
        Return $False

    If ($Members -contains $User) { 

        Return $True

    Else {

        Return $False



Add a new custom Powershell module path

You can use the following script to add a new module path to the PSModulePath environmental variable. Adding modules to this path will allow you to use them in your own scripts and if you have Powershell 3.0+ these modules will be automatically loaded when you call one of the custom CMDLET’s.

Please replace the $ModulePath variable with the path that you would like to use.

$ModulePath = "YOUR PATH HERE"
$Path = (Get-ItemProperty -Path "HKLM:\SYSTEM\ControlSet001\Control\Session Manager\Environment").PSModulePath
$NewPath = "$ModulePath" + ";" + $Path

If($Path -notlike "*$ModulePath*") {
    Set-ItemProperty -Path "HKLM:\SYSTEM\ControlSet001\Control\Session Manager\Environment" -Name PSModulePath -Type String -Value "$NewPath"

AC Power Check For Laptops

The following script can be used in an SCCM or MDT upgrade task sequence to check if a laptop is connected to a charger. If the script detects that the laptop is not connected to a charger, it will prompt the user to connect the laptop to AC power.

$ChassisTypes = (Get-WmiObject -Class Win32_SystemEnclosure).ChassisTypes

Switch($ChassisTypes) {

    3 { $Chassis = "Desktop" }
    4 { $Chassis = "Desktop" }
    5 { $Chassis = "Desktop" }
    6 { $Chassis = "Desktop" }
    7 { $Chassis = "Desktop" }
    8 { $Chassis = "Laptop" }
    9 { $Chassis = "Laptop" }
    10 { $Chassis = "Laptop" }
    11 { $Chassis = "Laptop" }
    12 { $Chassis = "Laptop" }
    14 { $Chassis = "Laptop" }
    15 { $Chassis = "Desktop" }
    16 { $Chassis = "Desktop" }
    18 { $Chassis = "Laptop" }
    21 { $Chassis = "Laptop" }
    23 { $Chassis = "Server" }
    31 { $Chassis = "Laptop" }

If($Chassis -eq "Laptop") {

    Do {
      $PowerStatus = (Get-WmiObject -Class BatteryStatus  -Namespace root\wmi -ErrorAction SilentlyContinue).PowerOnLine

        If($PowerStatus -ne $True) {

            $TSEnv = New-Object -ComObject "Microsoft.SMS.TsProgressUI"
            $wshell = New-Object -ComObject Wscript.Shell
            $wshell.Popup("Please Connect AC Power - Click OK to Continue",0,"AC Power Check",0)
    Until($PowerStatus -eq $True)