Tag: SCCM

All things related to SCCM

  • How to remove Classic teams?

    How to remove Classic teams?

    Update 11.11.2024: – https://learn.microsoft.com/en-us/microsoftteams/teams-client-uninstall-script
    M$ finally launched official script 8.11.2024. So there is your OFFICIAL way of doing this. Use the above.

    I bet when you have been googling, you haven’t found anything worthy results that actually makes the security portals hide the classic teams. Well I made a script that is bad, I mean its bad as it really should have been Microsoft all along to fix this and not IT admins.

    So this can be done with application based “install” or remediation based script.

    SCCM – Application example

    Detection method:

    # Microsoft Teams Classic Uninstall Detection
    $goRemediate = $false
    $UserProfiles = Get-ChildItem "C:\Users" -Directory
    $TeamsClassicFound = $false
    
    foreach ($profile in $UserProfiles) {
        $TeamsClassicPath = "$($profile.FullName)\AppData\Local\Microsoft\Teams\current\Teams.exe"
        if (Test-Path $TeamsClassicPath) {
            #write-host "Teams Classic found in user profile located in $($profile.FullName), setting remediation needs to $true"
            $TeamsClassicFound = $true
            break
        }
    }
    
    if (!$TeamsClassicFound) {
        #write-host "No Teams Classic found." -ForegroundColor Green
    } else {
       # write-host "Teams Classic was found, needs to be remediated."
        $goRemediate = $true
    }
    
    $registryPath = @(
        "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*",
        "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*"
    )
    $MachineWide = Get-ItemProperty -Path $registryPath | Where-Object -Property DisplayName -eq "Teams Machine-Wide Installer" 
    $classic = Get-WmiObject -Query "SELECT * FROM Win32_Product WHERE Name = 'Microsoft Teams classic'"
    $hkuKeys = Get-ChildItem -Path "Registry::HKEY_USERS"
    
    foreach ($userKey in $hkuKeys) {
        $teamsKeyPath = "Registry::HKEY_USERS\$($userKey.PSChildName)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Teams"
        if (Test-Path $teamsKeyPath) {
           # write-host "User registry still lurking, setting remediation needs to $true"
            $goRemediate = $true
        }
    }
    
    if ($MachineWide) {
        #write-host "Still lurking: Teams Machine-Wide Installer, setting remediation needs to $true"
        $goRemediate = $true
    }
    
    if ($classic) {
        #write-host "Still lurking: Microsoft Teams Classic Installer, setting remediation needs to $true"
        $goRemediate = $true
    }
    
    # Finding SIDs for loop
    $PatternSID = 'S-1-5-\d+-\d+-\d+\-\d+\-\d+$'
    
    # Get Username, SID, and location of ntuser.dat for all users
    $ProfileList = gp 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\*' | Where-Object {$_.PSChildName -match $PatternSID} | 
        Select  @{name="SID";expression={$_.PSChildName}}, 
                @{name="UserHive";expression={"$($_.ProfileImagePath)\ntuser.dat"}}, 
                @{name="Username";expression={$_.ProfileImagePath -replace '^(.*[\\\/])', ''}}
    
    # Get all user SIDs found in HKEY_USERS (ntuder.dat files that are loaded)
    $LoadedHives = gci Registry::HKEY_USERS | ? {$_.PSChildname -match $PatternSID} | Select @{name="SID";expression={$_.PSChildName}}
    
    # Get all users that are not currently logged
    $UnloadedHives = Compare-Object $ProfileList.SID $LoadedHives.SID | Select @{name="SID";expression={$_.InputObject}}, UserHive, Username
    
    # Loop through each profile on the machine
    Foreach ($item in $ProfileList) {
        IF ($item.SID -in $UnloadedHives.SID) {
            reg load HKU\$($Item.SID) $($Item.UserHive) | Out-Null
        }
    
        # Check and potentially remove outdated Teams versions
        $teamsUninstallKeys = Get-ItemProperty registry::HKEY_USERS\$($item.SID)\Software\Microsoft\Windows\CurrentVersion\Uninstall\Teams*
    
        if ($teamsUninstallKeys) {
            foreach ($teamsKey in $teamsUninstallKeys) {
                    #write-host "Teams found in user profile: $($item.Username) with version $displayVersion"
                    $goRemediate = $true
                }
            }
        }
    
        IF ($item.SID -in $UnloadedHives.SID) {
            [gc]::Collect()
            reg unload HKU\$($item.SID) | Out-Null
        }
    
    
    if (!$goRemediate) {
        write-output "Installed." 
    } 

    So as you might wonder. This is reverse logic. If not found then Installed. This app is only to remove and use “INSTALL” as the logic of which is build:

    So there you have the detection method and why its done weirdly.

    Application install – SCCM

    #"C:\ProgramData\Microsoft\IntuneManagementExtension\Logs"
    #"C:\Windows\CCM\Logs\TeamsUninstaller.log"
    $logFilePath = "C:\ProgramData\Microsoft\IntuneManagementExtension\Logs"
    
    function Log-Message {
        param (
            [string]$Message
        )
        $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
        Add-Content -Path $logFilePath -Value "$timestamp - $Message"
    }
    
    $UserProfiles = Get-ChildItem "C:\Users" -Directory
    $TeamsClassicFound = $false
    
    foreach ($profile in $UserProfiles) {
        $TeamsClassicPath = "$($profile.FullName)\AppData\Local\Microsoft\Teams\current\Teams.exe"
        if (Test-Path $TeamsClassicPath) {
            Log-Message "Teams Classic found in user profile located in $($profile.FullName)"
        }
    }
    
    if (!$TeamsClassicFound) {
        Log-Message "No Teams Classic found."
    }
    
    $registryPath = @(
        "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*",
        "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*"
    )
    $MachineWide = Get-ItemProperty -Path $registryPath | Where-Object -Property DisplayName -eq "Teams Machine-Wide Installer"
    Log-Message "$($MachineWide.DisplayName) Was found in the installed applications."
    
    $hkuKeys = Get-ChildItem -Path "Registry::HKEY_USERS"
    foreach ($userKey in $hkuKeys) {
        $teamsKeyPath = "Registry::HKEY_USERS\$($userKey.PSChildName)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Teams"
        if (Test-Path $teamsKeyPath) {
            Log-Message "User registry still lurking, setting remediation needs to true"
        }
    }
    
    function Uninstall-TeamsClassic($TeamsPath) {
        try {
            $process = Start-Process -FilePath "$TeamsPath\Update.exe" -ArgumentList "--uninstall /s" -PassThru -Wait -ErrorAction Stop
            if ($process.ExitCode -ne 0) {
                Log-Message "Uninstallation failed with exit code $($process.ExitCode)."
            }
        }
        catch {
            Log-Message "Uninstallation failed: $($_.Exception.Message)"
        }
    }
    
    $AllUsers = Get-ChildItem -Path "$($ENV:SystemDrive)\Users"
    
    foreach ($User in $AllUsers) {
        Log-Message "Processing user: $($User.Name)"
    
        $localAppData = "$($ENV:SystemDrive)\Users\$($User.Name)\AppData\Local\Microsoft\Teams"
        $programData = "$($env:ProgramData)\$($User.Name)\Microsoft\Teams"
    
        if (Test-Path "$localAppData\Current\Teams.exe") {
            Log-Message "Uninstall Teams for user $($User.Name)"
            Uninstall-TeamsClassic -TeamsPath $localAppData
        } elseif (Test-Path "$programData\Current\Teams.exe") {
            Log-Message "Uninstall Teams for user $($User.Name)"
            Uninstall-TeamsClassic -TeamsPath $programData
        } else {
            Log-Message "Teams installation not found for user $($User.Name)"
        }
    }
    
    $TeamsIcon_old = "$($ENV:SystemDrive)\Users\*\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Microsoft Teams*.lnk"
    Get-Item $TeamsIcon_old | Remove-Item -Force -Recurse
    
    $registryPath = @(
        "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*",
        "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*"
    )
    
    $MachineWide = Get-ItemProperty -Path $registryPath | Where-Object -Property DisplayName -eq "Teams Machine-Wide Installer"
    
    if ($MachineWide) {
        $registryKeyPath = $MachineWide.PSPath
        $cleanRegistryPath = $registryKeyPath -replace "Microsoft.PowerShell.Core\\Registry::", "Registry::"
        Remove-Item -Path $cleanRegistryPath -Recurse -Force
    } else {
         Log-Message "Teams Machine-Wide Installer not found in the registry."
    }
    
    $PatternSID = 'S-1-5-\d+-\d+-\d+\-\d+\-\d+$'
    $ProfileList = Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\*' | Where-Object {$_.PSChildName -match $PatternSID} | 
        Select  @{name="SID";expression={$_.PSChildName}}, 
                @{name="UserHive";expression={"$($_.ProfileImagePath)\ntuser.dat"}}, 
                @{name="Username";expression={$_.ProfileImagePath -replace '^(.*[\\\/])', ''}}
    
    $LoadedHives = Get-ChildItem Registry::HKEY_USERS | Where-Object {$_.PSChildname -match $PatternSID} | Select @{name="SID";expression={$_.PSChildName}}
    $UnloadedHives = Compare-Object $ProfileList.SID $LoadedHives.SID | Select @{name="SID";expression={$_.InputObject}}, UserHive, Username
    
    function Load-Hive {
        param (
            [string]$SID,
            [string]$HivePath
        )
    
        $maxRetries = 2
        $retryDelay = 2  # seconds
    
        for ($attempt = 1; $attempt -le $maxRetries; $attempt++) {
            try {
                # Attempt to load the hive
                reg load HKU\$SID $HivePath | Out-Null
                Log-Message "Successfully loaded hive for SID $SID"
                return $true
            } catch {
                Log-Message "Failed to load hive for SID $SID on attempt: $(${_}.Exception.Message)"
    
                if ($attempt -lt $maxRetries) {
                    Log-Message "Retrying in $retryDelay seconds..."
                    Start-Sleep -Seconds $retryDelay
                } else {
                    Log-Message "Maximum retries reached for loading hive $SID. Skipping this profile."
                    return $false
                }
            }
        }
    }
    
    foreach ($item in $ProfileList) {
        Log-Message "Checking $($item.Username)"
    
        if ($item.SID -in $UnloadedHives.SID) {
            Log-Message "Hive not loaded for $($item.Username). Attempting to load hive."
            $hiveLoaded = Load-Hive -SID $item.SID -HivePath $item.UserHive
    
            if (-not $hiveLoaded) {
                Log-Message "Skipping user $($item.Username) due to failed hive load."
                continue
            }
        }
    
        $teamsUninstallKeys = Get-ItemProperty registry::HKEY_USERS\$($item.SID)\Software\Microsoft\Windows\CurrentVersion\Uninstall\Teams*   
        if ($teamsUninstallKeys) {
            foreach ($teamsKey in $teamsUninstallKeys) {
                # Remove the Teams uninstall key
                Remove-Item -Path "registry::HKEY_USERS\$($item.SID)\Software\Microsoft\Windows\CurrentVersion\Uninstall\$($teamsKey.PSChildName)" -Recurse
                # Remove Teams folder from profile
                if ($teamsPath) {
                Remove-Item -Path $teamsPath -Recurse -Force
                }
            }
        }
    
        if ($item.SID -in $UnloadedHives.SID) {
            Log-Message "Unloading hive for $($item.Username)"
            [gc]::Collect()
            reg unload HKU\$($item.SID) | Out-Null
        }
    }
    exit 0

    This to run on client that have detected that there are still hints of Legacy Teams in user profiles or in some user accounts appdata folder.

    But that’s that then. Deploy with caution. This isn’t very professional way to approach this, but neither was Microsoft’s approach to deploy new teams and not do anything for legacy Teams.

    Intune Remediation

    Discovery script:

    # Microsoft Teams Classic Uninstall Detection
    $goRemediate = $false
    $UserProfiles = Get-ChildItem "C:\Users" -Directory
    $TeamsClassicFound = $false
    
    foreach ($profile in $UserProfiles) {
        $TeamsClassicPath = "$($profile.FullName)\AppData\Local\Microsoft\Teams\current\Teams.exe"
        if (Test-Path $TeamsClassicPath) {
            #write-host "Teams Classic found in user profile located in $($profile.FullName), setting remediation needs to $true"
            $TeamsClassicFound = $true
            break
        }
    }
    
    if (!$TeamsClassicFound) {
        #write-host "No Teams Classic found." -ForegroundColor Green
    } else {
       # write-host "Teams Classic was found, needs to be remediated."
        $goRemediate = $true
    }
    
    $registryPath = @(
        "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*",
        "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*"
    )
    $MachineWide = Get-ItemProperty -Path $registryPath | Where-Object -Property DisplayName -eq "Teams Machine-Wide Installer" 
    $classic = Get-WmiObject -Query "SELECT * FROM Win32_Product WHERE Name = 'Microsoft Teams classic'"
    $hkuKeys = Get-ChildItem -Path "Registry::HKEY_USERS"
    
    foreach ($userKey in $hkuKeys) {
        $teamsKeyPath = "Registry::HKEY_USERS\$($userKey.PSChildName)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Teams"
        if (Test-Path $teamsKeyPath) {
           # write-host "User registry still lurking, setting remediation needs to $true"
            $goRemediate = $true
        }
    }
    
    if ($MachineWide) {
        #write-host "Still lurking: Teams Machine-Wide Installer, setting remediation needs to $true"
        $goRemediate = $true
    }
    
    if ($classic) {
        #write-host "Still lurking: Microsoft Teams Classic Installer, setting remediation needs to $true"
        $goRemediate = $true
    }
    
    # Define minimum acceptable version (replace with your desired version)
    $minVersion = "1.7.0.4689"
    
    # Finding SIDs for loop
    $PatternSID = 'S-1-5-\d+-\d+-\d+\-\d+\-\d+$'
    
    # Get Username, SID, and location of ntuser.dat for all users
    $ProfileList = gp 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\*' | Where-Object {$_.PSChildName -match $PatternSID} | 
        Select  @{name="SID";expression={$_.PSChildName}}, 
                @{name="UserHive";expression={"$($_.ProfileImagePath)\ntuser.dat"}}, 
                @{name="Username";expression={$_.ProfileImagePath -replace '^(.*[\\\/])', ''}}
    
    # Get all user SIDs found in HKEY_USERS (ntuder.dat files that are loaded)
    $LoadedHives = gci Registry::HKEY_USERS | ? {$_.PSChildname -match $PatternSID} | Select @{name="SID";expression={$_.PSChildName}}
    
    # Get all users that are not currently logged
    $UnloadedHives = Compare-Object $ProfileList.SID $LoadedHives.SID | Select @{name="SID";expression={$_.InputObject}}, UserHive, Username
    
    # Loop through each profile on the machine
    Foreach ($item in $ProfileList) {
        IF ($item.SID -in $UnloadedHives.SID) {
            reg load HKU\$($Item.SID) $($Item.UserHive) | Out-Null
        }
    
        # Check and potentially remove outdated Teams versions
        $teamsUninstallKeys = Get-ItemProperty registry::HKEY_USERS\$($item.SID)\Software\Microsoft\Windows\CurrentVersion\Uninstall\Teams*
    
        if ($teamsUninstallKeys) {
            foreach ($teamsKey in $teamsUninstallKeys) {
                $displayVersion = $teamsKey.DisplayVersion
                if ($displayVersion -lt $minVersion) {
                    #write-host "Teams found in user profile: $($item.Username) with version $displayVersion"
                    $goRemediate = $true
                }
            }
        }
    
        IF ($item.SID -in $UnloadedHives.SID) {
            [gc]::Collect()
            reg unload HKU\$($item.SID) | Out-Null
        }
    }
    
    if (!$goRemediate) {
        write-output "Installed." 
    } 
    
    if ($goRemediate) {
        write-host "Issues detected. Proceeding with remediation."
        exit 1
    } else {
        write-host "No issues detected. No remediation needed."
        exit 0
    }
    

    Remediation:

    #"C:\ProgramData\Microsoft\IntuneManagementExtension\Logs"
    #"C:\Windows\CCM\Logs\TeamsUninstaller.log"
    $logFilePath = "C:\ProgramData\Microsoft\IntuneManagementExtension\Logs"
    
    function Log-Message {
        param (
            [string]$Message
        )
        $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
        Add-Content -Path $logFilePath -Value "$timestamp - $Message"
    }
    
    $UserProfiles = Get-ChildItem "C:\Users" -Directory
    $TeamsClassicFound = $false
    
    foreach ($profile in $UserProfiles) {
        $TeamsClassicPath = "$($profile.FullName)\AppData\Local\Microsoft\Teams\current\Teams.exe"
        if (Test-Path $TeamsClassicPath) {
            Log-Message "Teams Classic found in user profile located in $($profile.FullName)"
        }
    }
    
    if (!$TeamsClassicFound) {
        Log-Message "No Teams Classic found."
    }
    
    $registryPath = @(
        "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*",
        "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*"
    )
    $MachineWide = Get-ItemProperty -Path $registryPath | Where-Object -Property DisplayName -eq "Teams Machine-Wide Installer"
    Log-Message "$($MachineWide.DisplayName) Was found in the installed applications."
    
    $hkuKeys = Get-ChildItem -Path "Registry::HKEY_USERS"
    foreach ($userKey in $hkuKeys) {
        $teamsKeyPath = "Registry::HKEY_USERS\$($userKey.PSChildName)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Teams"
        if (Test-Path $teamsKeyPath) {
            Log-Message "User registry still lurking, setting remediation needs to true"
        }
    }
    
    function Uninstall-TeamsClassic($TeamsPath) {
        try {
            $process = Start-Process -FilePath "$TeamsPath\Update.exe" -ArgumentList "--uninstall /s" -PassThru -Wait -ErrorAction Stop
            if ($process.ExitCode -ne 0) {
                Log-Message "Uninstallation failed with exit code $($process.ExitCode)."
            }
        }
        catch {
            Log-Message "Uninstallation failed: $($_.Exception.Message)"
        }
    }
    
    $AllUsers = Get-ChildItem -Path "$($ENV:SystemDrive)\Users"
    
    foreach ($User in $AllUsers) {
        Log-Message "Processing user: $($User.Name)"
    
        $localAppData = "$($ENV:SystemDrive)\Users\$($User.Name)\AppData\Local\Microsoft\Teams"
        $programData = "$($env:ProgramData)\$($User.Name)\Microsoft\Teams"
    
        if (Test-Path "$localAppData\Current\Teams.exe") {
            Log-Message "Uninstall Teams for user $($User.Name)"
            Uninstall-TeamsClassic -TeamsPath $localAppData
        } elseif (Test-Path "$programData\Current\Teams.exe") {
            Log-Message "Uninstall Teams for user $($User.Name)"
            Uninstall-TeamsClassic -TeamsPath $programData
        } else {
            Log-Message "Teams installation not found for user $($User.Name)"
        }
    }
    
    $TeamsIcon_old = "$($ENV:SystemDrive)\Users\*\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Microsoft Teams*.lnk"
    Get-Item $TeamsIcon_old | Remove-Item -Force -Recurse
    
    $registryPath = @(
        "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*",
        "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*"
    )
    
    $MachineWide = Get-ItemProperty -Path $registryPath | Where-Object -Property DisplayName -eq "Teams Machine-Wide Installer"
    
    if ($MachineWide) {
        $registryKeyPath = $MachineWide.PSPath
        $cleanRegistryPath = $registryKeyPath -replace "Microsoft.PowerShell.Core\\Registry::", "Registry::"
        Remove-Item -Path $cleanRegistryPath -Recurse -Force
    } else {
         Log-Message "Teams Machine-Wide Installer not found in the registry."
    }
    
    $PatternSID = 'S-1-5-\d+-\d+-\d+\-\d+\-\d+$'
    $ProfileList = Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\*' | Where-Object {$_.PSChildName -match $PatternSID} | 
        Select  @{name="SID";expression={$_.PSChildName}}, 
                @{name="UserHive";expression={"$($_.ProfileImagePath)\ntuser.dat"}}, 
                @{name="Username";expression={$_.ProfileImagePath -replace '^(.*[\\\/])', ''}}
    
    $LoadedHives = Get-ChildItem Registry::HKEY_USERS | Where-Object {$_.PSChildname -match $PatternSID} | Select @{name="SID";expression={$_.PSChildName}}
    $UnloadedHives = Compare-Object $ProfileList.SID $LoadedHives.SID | Select @{name="SID";expression={$_.InputObject}}, UserHive, Username
    
    function Load-Hive {
        param (
            [string]$SID,
            [string]$HivePath
        )
    
        $maxRetries = 2
        $retryDelay = 2  # seconds
    
        for ($attempt = 1; $attempt -le $maxRetries; $attempt++) {
            try {
                # Attempt to load the hive
                reg load HKU\$SID $HivePath | Out-Null
                Log-Message "Successfully loaded hive for SID $SID"
                return $true
            } catch {
                Log-Message "Failed to load hive for SID $SID on attempt: $(${_}.Exception.Message)"
    
                if ($attempt -lt $maxRetries) {
                    Log-Message "Retrying in $retryDelay seconds..."
                    Start-Sleep -Seconds $retryDelay
                } else {
                    Log-Message "Maximum retries reached for loading hive $SID. Skipping this profile."
                    return $false
                }
            }
        }
    }
    
    foreach ($item in $ProfileList) {
        Log-Message "Checking $($item.Username)"
    
        if ($item.SID -in $UnloadedHives.SID) {
            Log-Message "Hive not loaded for $($item.Username). Attempting to load hive."
            $hiveLoaded = Load-Hive -SID $item.SID -HivePath $item.UserHive
    
            if (-not $hiveLoaded) {
                Log-Message "Skipping user $($item.Username) due to failed hive load."
                continue
            }
        }
    
        $teamsUninstallKeys = Get-ItemProperty registry::HKEY_USERS\$($item.SID)\Software\Microsoft\Windows\CurrentVersion\Uninstall\Teams*   
        if ($teamsUninstallKeys) {
            foreach ($teamsKey in $teamsUninstallKeys) {
                # Remove the Teams uninstall key
                Remove-Item -Path "registry::HKEY_USERS\$($item.SID)\Software\Microsoft\Windows\CurrentVersion\Uninstall\$($teamsKey.PSChildName)" -Recurse
                # Remove Teams folder from profile
                if ($teamsPath) {
                Remove-Item -Path $teamsPath -Recurse -Force
                }
            }
        }
    
        if ($item.SID -in $UnloadedHives.SID) {
            Log-Message "Unloading hive for $($item.Username)"
            [gc]::Collect()
            reg unload HKU\$($item.SID) | Out-Null
        }
    }
    exit 0

    That’s that then. Try and be careful. Do not deploy to all computers at once.

  • Setting up Modern Driver Management and Modern Bios Management – whole guide on how to setup

    Setting up Modern Driver Management and Modern Bios Management – whole guide on how to setup

    Highly recommended setup. Use it if you can. This will be the whole guide and I will cut this into two posts of BIOS and Drivers later on.

    Shoutout to guys in Modern Driver Management – MSEndpointMgr. They are really helping out the IT community with their tutorials.

    So big thanks to them!

    So lets start on where you should setup driver and bios install steps in SCCM task sequence:

    Here are the steps in my demo task sequence. These steps setup a variety of things, like read-only account that looks through the packages in driver or bios folders.

    So you need to set username and password. To have it somewhat secret use do not display this value as you setup the account. This means your account is logged in a format that hides every second letter to _-mark. Meaning if you use driver@de.mo your logged information about the account would be d_i_e_@_e_m_. Password is a no show all together, but this account has rights to read your SCCM so you really should precaution when using this. If you use security scope and apply it for MDM resources only then its not so big deal.

    There is also Lenovo and Dell being setup here and those are passwords also and we will be talking about them later on as well.

    BIOS updates

    So lets get into bios updates first. You need to get the base script: ModernBIOSManagement/Invoke-CMDownloadBIOSPackage.ps1 at main · MSEndpointMgr/ModernBIOSManagement · GitHub

    After you have run this step you need to place a folder that is guided by NewBIOSAvailable task sequence variable.

    Then you need device based scripts:

    HP

    ModernBIOSManagement/Invoke-HPBIOSUpdate.ps1 at main · MSEndpointMgr/ModernBIOSManagement · GitHub

    SELECT * FROM Win32_ComputerSystem WHERE Manufacturer LIKE “%HP%”

    DELL

    ModernBIOSManagement/Invoke-DellBIOSUpdate.ps1 at main · MSEndpointMgr/ModernBIOSManagement · GitHub

    SELECT * FROM Win32_ComputerSystem WHERE Manufacturer LIKE “%DELL%”

    Lenovo

    ModernBIOSManagement/Invoke-LenovoBIOSUpdate.ps1 at main · MSEndpointMgr/ModernBIOSManagement · GitHub

    SELECT * FROM Win32_ComputerSystem WHERE Manufacturer LIKE “%Lenovo%”

    Microsoft

    ModernBIOSManagement/Invoke-MicrosoftBIOSUpdate.ps1 at main · MSEndpointMgr/ModernBIOSManagement · GitHub

    Note to have these running you have to have the read-only account in your environment.

    SELECT * FROM Win32_ComputerSystem WHERE Manufacturer LIKE “%Microsoft%”

    Drivers

    If you have setup the above Bios variables also, then you don’t need to these once again. But to have MDM to only use drivers then you need 2 steps in your task sequence:

    Setup user variables. Remember to use Do not display this value when setting these.

    Read-only account

    Easily done. Create a domain user that will the have the rights on SCCM database in Read-only mode.