Wednesday, 11 June 2025

BitLocker Remediation Script for SCCM & Intune

 

This blog walks you through a PowerShell script that automates BitLocker encryption, validates TPM status, and logs all activity to a file—perfect for automated deployments via SCCM, Intune, or GPO.


Key Features of the Script

  • 🔍 Checks TPM presence and status
  • 🔐 Verifies BitLocker encryption and protection status
  • 🔄 Enables encryption and protection if required
  • ☁️ Backs up BitLocker recovery keys to Azure AD
  • 📃 Logs actions with timestamps and severity levels

🧩 PowerShell Script Breakdown

Below is the complete PowerShell script. You can save this as Enable-BitLocker.ps1 and deploy it as needed.

Function Get-LoggedInUser {

    [CmdletBinding()]

    param(

        [Parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 0)]

        [string[]] $ComputerName = $env:COMPUTERNAME,

 

        [Parameter(Mandatory = $false)]

        [Alias("SamAccountName")]

        [string]   $UserName

    )

    PROCESS {

        foreach ($Computer in $ComputerName) {

            try {

                $Computer = $Computer.ToUpper()

                $SessionList = quser /Server:$Computer 2>$null

                if ($SessionList) {

                    $UserInfo = foreach ($Session in ($SessionList | select -Skip 1)) {

                        $Session = $Session.ToString().trim() -replace '\s+', ' ' -replace '>', ''

                        if ($Session.Split(' ')[3] -eq 'Active') {

                            [PSCustomObject]@{

                                ComputerName = $Computer

                                UserName     = $session.Split(' ')[0]

                                SessionName  = $session.Split(' ')[1]

                                SessionID    = $Session.Split(' ')[2]

                                SessionState = $Session.Split(' ')[3]

                                IdleTime     = $Session.Split(' ')[4]

                                LogonTime    = $session.Split(' ')[5, 6, 7] -as [string] -as [datetime]

                            }

                        } else {

                            [PSCustomObject]@{

                                ComputerName = $Computer

                                UserName     = $session.Split(' ')[0]

                                SessionName  = $null

                                SessionID    = $session.Split(' ')[1]

                                SessionState = 'Disconnected'

                                IdleTime     = $Session.Split(' ')[3]

                                LogonTime    = $session.Split(' ')[4, 5, 6] -as [string] -as [datetime]

                            }

                        }

                    }

                    if ($PSBoundParameters.ContainsKey('Username')) {

                        $UserInfo | Where-Object {$_.UserName -eq $UserName}

                    } else {

                        $UserInfo | Sort-Object LogonTime

                    }

                }

            } catch {

                Write-Error $_.Exception.Message

            }

        }

    }

}

 

Function Out-LogFile {

    Param(

        [Parameter(Mandatory = $false)] $Text,

        $Mode,

        [Parameter(Mandatory = $false)][ValidateSet(1, 2, 3, 'Information', 'Warning', 'Error')]$Severity = 1

    )

 

    switch ($Severity) {

        'Information' {$Severity = 1}

        'Warning' {$Severity = 2}

        'Error' {$Severity = 3}

    }

 

    $clientpath = 'C:\Windows'

    $Logfile = "$clientpath\temp\BitlockerAzure.log"

 

    foreach ($item in $text) {

        $item = '<![LOG[' + $item + ']LOG]!>'

        $time = 'time="' + (Get-Date -Format HH:mm:ss.fff) + '+000"'

        $date = 'date="' + (Get-Date -Format MM-dd-yyyy) + '"'

        $component = 'component="BitlockerScript"'

        $context = 'context=""'

        $type = 'type="' + $Severity + '"'

        $thread = 'thread="' + $PID + '"'

        $file = 'file=""'

        $logblock = ($time, $date, $component, $context, $type, $thread, $file) -join ' '

        $logblock = '<' + $logblock + '>'

        $item + $logblock | Out-File -Encoding utf8 -Append $logFile

    }

}

 

function Get-TPMStatus {

    try {

        $tpm = Get-WmiObject -Namespace "Root\CIMv2\Security\MicrosoftTpm" -Class Win32_Tpm

        if ($tpm) {

            if ($tpm.IsEnabled -eq $false) {

                return "TPM is turned off"

            } elseif ($tpm.IsPresent -eq $false) {

                return "No TPM present"

            } else {

                return "TPM is enabled"

            }

        } else {

            return "No TPM information available"

        }

    } catch {

        return "Error retrieving TPM status"

    }

}


 

💡 Deployment Tips

  • Run as Administrator – TPM and BitLocker commands require elevated privileges.
  • Log Review – Review C:\Windows\Temp\BitlockerAzure.log for audit and debugging.
  • Use with Intune or Task Scheduler for zero-touch deployments.
  • Test on a VM or staging environment before deploying widely.

Wednesday, 9 April 2025

SCCM Collection Relationships Using SQL Queries

 In System Center Configuration Manager (SCCM), collections are used to group systems or devices based on specific criteria for easier management. But how do these collections relate to each other? In this blog post, we’ll explore how to find relationships between collections, such as including, excluding, or limiting systems in source collections using SQL queries in SCCM.

Understanding Collection Relationships in SCCM

SCCM allows administrators to manage collections by creating dependencies between them. These dependencies determine how one collection impacts another. You may have scenarios where one collection is a subset of another (limited), one collection is included in another (include), or one collection excludes another collection (exclude).

SCCM maintains collection dependencies in the vSMS_CollectionDependencies table, which stores the relationship between a source collection and a dependent collection.

Key Columns Involved

  • SourceCollectionID: The ID of the collection that is the source of the dependency.
  • DependentCollectionID: The ID of the collection that is dependent on the source collection.
  • RelationshipType: The type of relationship, where:
    • 1 = Limited To
    • 2 = Include
    • 3 = Exclude

Using SQL to Query Collection Relationships

You can use SQL queries to extract details about collection relationships in SCCM. Below is a SQL query that will help you retrieve the relationships for a specific source collection

SELECT

    v_Collection.name,

    v_Collections.CollectionName AS [Source Collection Name],

    SourceCollectionID,

    CASE

        WHEN vSMS_CollectionDependencies.relationshiptype = 1 THEN 'Limited To ' + SourceCollectionID

        WHEN vSMS_CollectionDependencies.relationshiptype = 2 THEN 'Include ' + SourceCollectionID

        WHEN vSMS_CollectionDependencies.relationshiptype = 3 THEN 'Exclude ' + SourceCollectionID

    END AS "Type of Relationship"

FROM

    v_Collection

JOIN

    vSMS_CollectionDependencies ON vSMS_CollectionDependencies.DependentCollectionID = v_Collection.CollectionID

JOIN

    v_Collections ON v_Collections.SiteID = vSMS_CollectionDependencies.SourceCollectionID

WHERE

    vSMS_CollectionDependencies.SourceCollectionID LIKE 'CollectionID';

Conclusion

Using SQL queries to analyze collection relationships in SCCM can save time and improve your ability to manage your environment efficiently. The query shared in this blog will help you gain insights into how collections are interdependent and ensure that your configuration management policies are applied correctly.

Friday, 4 April 2025

Windows LAPS with Intune


Windows Local Administrator Password Solution (LAPS) has been a crucial tool for securing local administrator accounts in managed Windows devices. With the recent Windows 24H2 update, Microsoft has introduced several enhancements to LAPS, empowering IT administrators with new options for automatic account management and increased flexibility for password security policies. One of the standout improvements is the ability to create managed accounts and configure automatic account management directly from Intune, making it easier than ever to enforce security standards across your devices.

 

Key Features of LAPS in Windows 24H2

With the release of Windows 24H2, Microsoft has made several improvements to LAPS, including the ability to define policies that streamline the management of local administrator accounts through Intune. The primary update is the inclusion of new policies for **Automatic Account Management**, which makes it easier to automate and enforce the creation, management, and maintenance of local administrator accounts. Additionally, administrators can now randomize the account name for an added layer of security.

 

New LAPS Policies in Intune

With these updates, administrators can now leverage the **Configuration Service Provider (CSP)** to define policies for LAPS in Microsoft Intune. Below are the essential CSPs that are now available to configure LAPS policies:

 

1. **`./Device/Vendor/MSFT/LAPS/Policies/AutomaticAccountManagementEnabled`** 

   This policy allows administrators to enable or disable automatic management of the local administrator account.

 

2. **`./Device/Vendor/MSFT/LAPS/Policies/AutomaticAccountManagementEnableAccount`** 

   This policy controls whether or not the local administrator account is automatically created and managed via LAPS.

 

3. **`./Device/Vendor/MSFT/LAPS/Policies/AutomaticAccountManagementNameOrPrefix`** 

   Here, administrators can define a name or prefix for the local administrator account. The flexibility to define custom account names is crucial for organizations with specific naming conventions.

 

4. **`./Device/Vendor/MSFT/LAPS/Policies/AutomaticAccountManagementRandomizeName`** 

   This policy allows the administrator to randomize the local administrator account name, which enhances security by reducing the predictability of the account name.

 

5. **`./Device/Vendor/MSFT/LAPS/Policies/AutomaticAccountManagementTarget`** 

   This policy defines the target device group or specific devices that will be subject to LAPS management.

 

6. **`./Device/Vendor/MSFT/LAPS/Policies/BackupDirectory`** 

   This policy specifies the backup directory for LAPS password storage, ensuring that backup copies of passwords are safely stored for recovery when needed.

 

Configuring LAPS Policies in Intune

To create a new LAPS policy via Intune, administrators can use the aforementioned CSPs in the **Device Configuration** section. These settings can be pushed to managed Windows devices, allowing for centralized control over the local administrator account security.

 

1. **Navigate to Intune > Devices > Configuration Profiles** in the Intune portal.

2. **Create a New Profile** and select **Windows 10 and later** as the platform.

3. **Choose the Profile Type** as **Custom**, and under **OMA-URI Settings**, you can input the appropriate CSPs based on your requirements.

 

Once configured, these settings will be applied to the managed devices, ensuring the local administrator account is automatically created and secured according to the defined policies.

 

Backup and Recovery Considerations

As part of the improved LAPS functionality, administrators are now encouraged to set up a backup directory for storing passwords securely. This ensures that in the event of an emergency or a recovery scenario, administrators can retrieve the local administrator password for troubleshooting and remediation.

 

For more detailed information on configuring backup directories and additional LAPS policy options, refer to the official [Microsoft documentation on LAPS

CSP](https://learn.microsoft.com/en-us/windows/client-management/mdm/laps-csp#policiesbackupdirectory).

 

Conclusion

The introduction of **Automatic Account Management** in Windows LAPS (available in the latest Windows 24H2 update) represents a significant step forward in securing local administrator accounts in a streamlined, automated manner. With the ability to manage account names, randomize credentials, and enforce automatic updates directly through Intune, organizations can enhance their security posture while reducing the administrative overhead of managing these critical accounts.


Thursday, 20 March 2025

Automating Email Alerts for Non-Compliant Devices in Intune via PowerShell and Graph API

Managing devices through Microsoft Intune requires efficient tracking of device compliance, and one key task for administrators is to keep users informed about the status of their devices. In some cases, users may have devices that are not compliant with your organization’s policies. To automate the process of notifying these users, you can use the Microsoft Graph API in combination with PowerShell to send an email to users whose devices are non-compliant.

In this blog post, we'll walk through a PowerShell script that pulls non-compliant device data from Intune via the Microsoft Graph API and sends a notification email to the user informing them about the non-compliant status.

Prerequisites:

Before running the script, ensure the following prerequisites are met:

  1. Microsoft Graph PowerShell SDK is installed. You can install it with the following command:

                                Install-Module Microsoft.Graph -Scope CurrentUser

  1. Permissions: Make sure your account has the necessary Microsoft Graph API permissions to read device data and send emails. The required permissions are:
    • DeviceManagementManagedDevices.ReadWrite.All to manage devices.
    • User.Read to read user information.
  2. SMTP Server Setup: You need access to an SMTP server (in this case, Office 365) to send emails.
  3. PowerShell Version: Ensure you are using PowerShell 7.x or a version that supports the required modules.

PowerShell Script to Send Emails to Non-Compliant Users

Here is a simple PowerShell script to get the non-compliant devices and send an email to the respective users:

# Connect to Microsoft Graph

# Connect to Microsoft Graph

Connect-MgGraph -Scopes "DeviceManagementManagedDevices.ReadWrite.All", "User.Read"

 

# Get the list of non-compliant devices

$nonCompliantDevices = Get-MgDeviceManagementManagedDevice -Filter "complianceState eq 'noncompliant'"

 

# Check if we found any non-compliant devices

if ($nonCompliantDevices -eq $null -or $nonCompliantDevices.Count -eq 0) {

    Write-Host "No non-compliant devices found."

    exit

}

 

# Loop through each non-compliant device and send an email

foreach ($device in $nonCompliantDevices) {

    # Display device details in console (for debugging)

    Write-Host "User: $($device.userPrincipalName)"

    Write-Host "Device Name: $($device.deviceName)"

    Write-Host "Compliance State: $($device.complianceState)"

    Write-Host "----------------------------------------------------------"

 

    # Prepare email subject and body

    $subject = "Non-Compliant Device"

    $body = "Device $($device.deviceName) assigned to $($device.userPrincipalName) is not currently compliant."

   

    # Email settings

    $smtpServer = "smtp.office365.com"

    $from = "IntuneAdmin@domain.com"

    $to = $device.userPrincipalName

    $port = 587

 

    # Ensure email address is valid

    if ($to -match "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$") {

        try {

            # Send email using SMTP

            Send-MailMessage -To $to -Subject $subject -Body $body -SmtpServer $smtpServer -From $from -UseSsl -Port $port

            Write-Host "Email sent to: $to"

        } catch {

            Write-Error "Failed to send email to $to. Error: $_"

        }

    } else {

        Write-Host "Invalid email address for user: $($device.userPrincipalName)"

    }

}

 

# Optional: Disconnect from the Graph API after the operation

Disconnect-MgGraph

Useful References:

  1. Microsoft Graph PowerShell SDK documentation: https://learn.microsoft.com/en-us/powershell/microsoftgraph/intune/introduction

Conclusion:

By using the Microsoft Graph API and PowerShell, you can easily automate the process of identifying non-compliant devices in Microsoft Intune and sending out notifications to users. This script helps improve compliance management and ensures that users are promptly informed of any issues with their devices.

 

Wednesday, 19 March 2025

SCCM Audit: 3 Methods to Identify Audit Status

 When managing an SCCM (System Center Configuration Manager) environment, it’s crucial to regularly audit your deployments, installations, and overall system health. Fortunately, SCCM provides various options to identify audit statuses and troubleshoot potential issues. In this blog post, we'll explore three methods you can use to identify the audit status in SCCM: Status Filter Rule, Default Report, and SQL Query. We'll also provide a sample SQL query to help you get the audit status based on Message ID and strings.

1. Using Status Filter

The first method to track audit status is by using the Status Filter in the SCCM console. This option allows you to filter messages based on criteria such as message type, severity, and date.

To use the Status Filter:

  • Navigate to Monitoring in the SCCM Console.
  • Under System Status, select Status Messages.
  • Use the filtering options to narrow down to the specific status you're looking for.

This is a quick and easy way to check the status of various tasks within SCCM, including package deployments and client health.

2. Using Default Report

SCCM also provides a set of default built-in reports, which are useful for auditing purposes. These reports provide visibility into package deployments, software updates, client activity, and more.

To access default reports:

  • Go to the Monitoring workspace in the SCCM Console.
  • Under Reporting, select Reports.
  • Browse the list of available reports and select the one relevant to your audit.

These reports are pre-configured to give you insights into various aspects of your environment, such as package distribution, client status, and software update compliance.

3. Using SQL Query

If you want more flexibility and advanced querying capabilities, SQL queries are a powerful tool. You can directly query the SCCM database to retrieve audit information based on specific message IDs and strings.

Below is an example SQL query to help you get audit status based on the Message ID and Message String:

SELECT *

FROM vStatusMessagesWithStrings

WHERE MessageID = '30000'

AND InsStrValue3 LIKE '%packagename%'

In this query:

  • vStatusMessagesWithStrings is the SCCM view that contains status messages along with their associated strings.
  • MessageID = '30000' filters the messages for a specific ID, in this case, 30000 (this ID represents a specific status event such as successful package deployment).
  • InsStrValue3 LIKE '%packagename%' further narrows the results to only show messages containing the package name.

Microsoft Technet Blog on Status Message IDs

For further information on the different Message IDs in SCCM, you can refer to the Microsoft Technet Blog. The blog provides an extensive list of SCCM Status Message IDs and their titles. This will help you understand what each message ID represents and how you can use them for better auditing.

Here is the link to the Microsoft Technet Blog that contains detailed information on status message IDs.

Conclusion

By using Status Filter, Default Reports, or SQL Queries, you can effectively track and monitor the audit status of your SCCM environment. SQL queries, in particular, offer advanced flexibility for detailed audits. The sample query provided above is just one example, and you can modify it according to your specific needs. For further reference, the Microsoft Technet Blog provides a complete list of status message IDs and their explanations, which will be extremely helpful for identifying and troubleshooting issues within your SCCM environment.

Stay on top of your SCCM environment's health, and leverage these methods for effective auditing and troubleshooting

Tuesday, 11 March 2025

Windows Update Management from SCCM to Intune

Moving Windows Update Workload from SCCM to Intune and Cleanup GPO Registry Keys for Smooth Intune Update Deployment

As organizations increasingly adopt Intune for modern device management, it becomes necessary to transition certain workloads, such as Windows Update management, from SCCM (System Center Configuration Manager) to Intune. This shift enables you to leverage cloud-based management, offering benefits like simplified administration and greater flexibility.

 

In this blog post, we'll explore how to move the Windows Update workload from SCCM to Intune and use PowerShell scripts to clean up old Group Policy Objects (GPO) registry keys that may interfere with Intune-based update management. Additionally, we will discuss how to use detection and remediation scripts to ensure the devices are ready for Intune update deployment.

 

Steps to Move Windows Update Workload from SCCM to Intune

Before you can move your Windows Update management from SCCM to Intune, you need to follow a few steps to properly set up your environment for Intune-based Windows Update management:

 

1. Disable SCCM Software Update Point (SUP)

The Software Update Point (SUP) role in SCCM manages Windows updates. To transition this responsibility to Intune, the first step is to disable the update management in SCCM.

 

In SCCM, go to Administration > Site Configuration > Sites.

Right-click on the site where the SUP role is installed, and select Remove Roles.

Uncheck the Software Update Point and confirm the removal.

2. Enable Windows Update for Business (WUfB) in Intune

Next, configure Windows Update for Business (WUfB) policies in Intune to manage updates:

 

In the Microsoft Endpoint Manager Admin Center, navigate to Devices > Windows > Update Rings for Windows 10 and later.

Create a new update ring that defines when and how updates are deployed to your devices.

Configure update settings like deferral periods, active hours, and automatic update behavior.

3. Assign Update Rings to Devices

Once the update rings are configured, assign them to relevant groups or devices in your environment. This ensures that Intune will control how and when updates are deployed to these devices.

 

Using PowerShell Scripts for GPO Registry Cleanup

When transitioning to Intune-managed updates, you may need to clean up old Group Policy registry keys set by SCCM, WSUS, or previous GPO configurations. These old registry settings can interfere with Intune’s update management.

 

We will use a PowerShell script for detection and remediation of Windows Update-related registry keys.

 

Detection Script: Check for Existing GPO Registry Settings

This script checks if any Windows Update-related registry keys are still present, indicating that Windows Update is being managed by an old GPO. If found, it will return a non-compliant status.

 

# WU Registry Key Detection Script

$regPath = "HKLM:\Software\Policies\Microsoft\Windows\WindowsUpdate"

$keys = Get-ItemProperty -Path $regPath -ErrorAction SilentlyContinue

 

if ($keys) {

    Write-Output "Windows Update GPO settings found"

    exit 1  # Non-compliant status

} else {

    Write-Output "No Windows Update GPO settings found"

    exit 0  # Compliant status

}

Remediation Script: Clean Up Registry Keys

If the detection script finds Windows Update GPO settings, the remediation script will delete the associated registry keys, ensuring that Intune can take over Windows Update management.

 

# Remediation Script to clean up GPO registry keys for Intune update deployment

 

# Define the registry paths to be deleted

$registryPaths = @(

    "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate",

    "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU"

)

 

# Function to delete registry keys

function Remove-RegistryKey {

    param (

        [string]$path

    )

    if (Test-Path $path) {

        Remove-Item -Path $path -Recurse -Force

        Write-Host "Deleted registry key: $path"

    } else {

        Write-Host "Registry key not found: $path"

    }

}

 

# Delete the registry keys

foreach ($path in $registryPaths) {

    Remove-RegistryKey -path $path

}

 

# Restart Windows Update service to apply changes

Restart-Service -Name wuauserv

 

Write-Host "Registry cleanup complete. The device is now ready for Intune update deployment."

Additional Detection Script: Verify Windows Update Service (WUfB)

This script checks whether the Windows Update service is being managed by Intune (via Windows Update for Business). If it is, the device is ready for Intune updates.

# Detection Script to verify if Windows Update is managed by Intune (WUfB)

$WUServiceManager = New-Object -ComObject "Microsoft.Update.ServiceManager"

$WUService = $WUServiceManager.Services | Where-Object { $_.IsDefaultAUService -eq $true }

$WUServiceNameDetails = $WUService.Name

 

if ($WUService.Name -eq "Microsoft Update") {

    Write-Output "Intune (WUfB) - $WUServiceNameDetails."

    Exit 0  # Compliant

} else {

    Write-Output "Not Intune (WUfB) - $WUServiceNameDetails."

    Exit 1  # Non-compliant

}

This detection script will help confirm that the Microsoft Update service is controlled by Intune’s Windows Update for Business (WUfB) settings.

 

Conclusion

Transitioning the Windows Update workload from SCCM to Intune allows for a modern, cloud-based approach to update management. By cleaning up old GPO registry keys and verifying that devices are configured for Intune-managed updates, you ensure a smooth and seamless update process for your organization's devices.

By using PowerShell scripts for detection and remediation, you automate the process of preparing devices for Windows Update for Business (WUfB) in Intune, making the transition efficient and secure.

Monday, 10 March 2025

Troubleshooting of SCCM Windows Update Deployment with PowerShell Scripts

 

Introduction

Managing and deploying Windows Updates in an enterprise environment can sometimes become a challenging task. Often, updates fail to install or are stuck in a pending state. When troubleshooting such issues in an SCCM (System Center Configuration Manager) environment, PowerShell scripts can be a powerful tool to monitor, remediate, and resolve common issues. This blog post will guide you through using PowerShell scripts within SCCM Configuration Items (CI) for monitoring and remediating Windows Update deployment issues.

We'll walk through:

  1. Monitoring Windows Update Folder Activity with a PowerShell script.
  2. Remediation of Common Windows Update Issues using PowerShell, such as stopping update services, clearing cache, and resetting configurations.

1. Monitoring Script: Checking Windows Update Folder Activity

The first step in troubleshooting Windows Update issues is to ensure the update files are being handled correctly. The SoftwareDistribution folder stores update-related files, and if it's not being updated regularly, it could indicate a problem with the update process.

Monitor Script:

# Define the folder path you want to check

$folderPath = "C:\Windows\SoftwareDistribution"

# Get the current date

$currentDate = Get-Date

# Get the folder's LastWriteTime property

$folderLastModified = (Get-Item $folderPath).LastWriteTime

# Calculate the time span between the current date and the folder's last modification date

$timeSpan = $currentDate - $folderLastModified

# Check if the folder was last modified within the last 15 days

if ($timeSpan.TotalDays -le 15) {

    Write-Host "Compliant"

} else {

    Write-Host "Non-Compliant"

}


2. Remediation Script: Resolving Windows Update Issues

When updates aren't working as expected, it's time to run a remediation script. This script will:

  • Stop Windows Update services.
  • Clear out old update cache and logs.
  • Rename the SoftwareDistribution and CatRoot2 folders (which may become corrupted).
  • Reset client settings and force discovery of new updates.

Remediation Script:

$arch = Get-WMIObject -Class Win32_Processor -ComputerName LocalHost | Select-Object AddressWidth

$ErrorActionPreference = 'SilentlyContinue'

Write-Host "1. Stopping Windows Update Services..."

Stop-Service -Name BITS -Force

Stop-Service -Name wuauserv -Force

Stop-Service -Name appidsvc -Force

Stop-Service -Name cryptsvc -Force

Write-Host "2. Remove QMGR Data file..."

Remove-Item "$env:allusersprofile\Application Data\Microsoft\Network\Downloader\qmgr*.dat" -ErrorAction SilentlyContinue

Stop-Service -Name BITS -Force

Stop-Service -Name wuauserv -Force

Stop-Service -Name appidsvc -Force

Stop-Service -Name cryptsvc -Force

Write-Host "3. Renaming the Software Distribution and CatRoot Folder..."

Remove-Item $env:systemroot\SoftwareDistribution.bak -Force -Recurse

Rename-Item $env:systemroot\SoftwareDistribution SoftwareDistribution.bak -ErrorAction SilentlyContinue

Rename-Item $env:systemroot\System32\Catroot2 catroot2.bak -ErrorAction SilentlyContinue

Write-Host "4. Removing old Windows Update log..."

Remove-Item $env:systemroot\WindowsUpdate.log -ErrorAction SilentlyContinue

Stop-Service -Name BITS -Force

Stop-Service -Name wuauserv -Force

Stop-Service -Name appidsvc -Force

Stop-Service -Name cryptsvc -Force

Write-Host "5. Resetting the Windows Update Services to default settings..."

"sc.exe sdset bits D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;AU)(A;;CCLCSWRPWPDTLOCRRC;;;PU)"

"sc.exe sdset wuauserv D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;AU)(A;;CCLCSWRPWPDTLOCRRC;;;PU)"

Set-Location $env:systemroot\system32

Write-Host "6) Removing WSUS client settings..."

REG DELETE "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate" /v AccountDomainSid /f

REG DELETE "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate" /v PingID /f

REG DELETE "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate" /v SusClientId /f

Write-Host "7) Delete all BITS jobs..."

Get-BitsTransfer | Remove-BitsTransfer

Write-Host "8) Starting Windows Update Services..."

Start-Service -Name BITS -Force

Start-Service -Name wuauserv -Force

Start-Service -Name appidsvc -Force

Start-Service -Name cryptsvc -Force

Start-Sleep -Seconds 10

Invoke-WmiMethod -Namespace "root\ccm" -Class "SMS_Client" -Name "ResetPolicy" -ArgumentList 1

Start-Sleep -Seconds 10

Invoke-WmiMethod -Namespace root\ccm -Class sms_client -Name TriggerSchedule "{00000000-0000-0000-0000-000000000021}"

Start-Sleep -Seconds 10

Invoke-WmiMethod -Namespace root\ccm -Class sms_client -Name TriggerSchedule "{00000000-0000-0000-0000-000000000113}"

Start-Sleep -Seconds 10

Invoke-WmiMethod -Namespace root\ccm -Class sms_client -Name TriggerSchedule "{00000000-0000-0000-0000-000000000114}"

Start-Sleep -Seconds 10

Invoke-WmiMethod -Namespace root\ccm -Class sms_client -Name TriggerSchedule "{00000000-0000-0000-0000-000000000026}"

Write-Host "9) Forcing discovery..."

wuauclt /resetauthorization /detectnow

 

Write-Host "Process complete. Please reboot your computer."


Conclusion

By using SCCM Configuration Items (CI) and PowerShell scripts, you can efficiently monitor and remediate Windows Update issues in your environment. The monitoring script helps identify whether updates are happening, while the remediation script tackles common update failures and clears the way for a successful update process.

BitLocker Remediation Script for SCCM & Intune

  This blog walks you through a PowerShell script that automates BitLocker encryption, validates TPM status, and logs all activity to a fil...