Disable SMB1 with PowerShell and SCCM

There are many reasons to disable and stop using SMB1 in Windows.  It’s insecure and isn’t efficient either.  I’m not the first to mention that it should be disabled and likely won’t be the last.

With that in mind, Microsoft has a page on how to disable it (linked below), but I’ll go through a simple way to use SCCM and PowerShell to ensure it’s disabled across your fleet.

Updated: 2017/05/13

Thanks to Rok B added fix for Server 2012 and expanded the script to handle Vista and Server 2008 as well while fixing the 2012 error.  Thanks to J Luke for the feedback regarding users without access to SCCM.

Microsoft Support Article: How to detect, enable and disable SMBv1, SMBv2, and SMBv3 in Windows and Windows Server

To disable this across a fleet of machines easily, we’re going to use SCCM Configuration Items.  If you don’t have SCCM, you could alternatively use a Group Policy Scheduled Task with the “Disable” script as it will handle detection and disabling the protocol in one script.  You won’t get a compliance report, although you could easily modify the script to write a log file somewhere to capture that information.

With SCCM, Configuration Items are fairly straightforward.  They involve a “detection” method that will allow you to assess compliance.  Depending on what you’re using to detect, you may also specify remediation options.  We’re going to use a PowerShell script for both.

I’d recommend you download a copy of the detection and remediation scripts from the following page.  Formatting on this page may not be exactly as it is in the scripts.  The code potentially could be newer as well.

From the SCCM Console go to Assets and Compliance > Compliance SettingsConfiguration Items

Select Create Configuration Item and set a name (e.g. SMBv1 – Disable).  Optionally enter a description such as Disables SMBv1 if enabled.  Select Next.

Select the operating systems this will apply to.  Deselect Windows XP, Windows 2003, and Windows XP Embedded (in Windows Embedded) as we’re targeting pretty much everything else.

Select New on the Specify settings for the operating system page.  Change Setting Type to Script and the Data Type to Boolean.

Under Discovery Script select Add Script…. Set the Script language to PowerShell and select Open… and browse to the files you downloaded to detect if SMBv1 is enabled (if retrieved from GitHub), or you can copy and paste in the following:

Try {
    [string]$OperatingSystemVersion = (Get-WmiObject -Class Win32_OperatingSystem).Version
    
    switch -Regex ($OperatingSystemVersion) {
        '(^10\.0.*|^6\.3.*)' 
            {
                # Windows 8.1 / Server 2012 R2 / Windows 10 / Server 2016
                if (((Get-SmbServerConfiguration).EnableSMB1Protocol) -or (((Get-WindowsOptionalFeature -Online -FeatureName SMB1Protocol).State) -match 'Enable(d|Pending)')) {
                    Return $true
                }
            }
        '^6\.2.*' 
            {
                # Windows 8 / Server 2012
                if (((Get-SmbServerConfiguration).EnableSMB1Protocol) -or ((sc.exe qc lanmanworkstation) -match 'MRxSmb10')) {
                    Return $true
                }
            }
        '^6\.(0|1).*'
            {
                # Windows Vista / Server 2008 / Windows 7 / Server 2008R2
                if ((((Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" -Name SMB1 -ErrorAction SilentlyContinue).SMB1) -ne '0') -or ((sc.exe qc lanmanworkstation) -match 'MRxSMb10')) {
                    Return $true
                }
            }
        default {
            Throw "Unsupported Operating System"
        }
    }


    Return $false


} Catch {
    $LastError = $Error | Select-Object -First 1 -ExpandProperty Exception | Select-Object -ExpandProperty Message
    Write-Warning -Message $LastError
    Exit 1
}

Select OK and repeat for the remediation script with the file downloaded earlier, or copy and paste the following:

Try {
    [string]$OperatingSystemVersion = (Get-WmiObject -Class Win32_OperatingSystem).Version    
    switch -Regex ($OperatingSystemVersion) {
        '(^10\.0.*|^6\.3.*)' 
            {
                # Windows 8.1 / Server 2012 R2 / Windows 10 / Server 2016
                
                # SMB1 Server Settings
                if ((Get-SmbServerConfiguration).EnableSMB1Protocol) {
                    Set-SmbServerConfiguration -EnableSMB1Protocol $false -Force
                }


                # SMB1 Client Settings
                if (((Get-WindowsOptionalFeature -Online -FeatureName SMB1Protocol).State) -match 'Enable(d|Pending)') {
                    Disable-WindowsOptionalFeature -Online -FeatureName SMB1Protocol -NoRestart
                }
            }
        '^6\.2.*' 
            {
                # Windows 8 / Server 2012
                
                # SMB1 Server Settings
                if ((Get-SmbServerConfiguration).EnableSMB1Protocol) {
                    Set-SmbServerConfiguration -EnableSMB1Protocol $false -Force
                }


                # SMB1 Client Settings
                if ((sc.exe qc lanmanworkstation) -match 'MRxSmb10') {
                    Start-Process -FilePath "$env:windir\System32\sc.exe" -ArgumentList 'config lanmanworkstation depend= bowser/mrxsmb20/nsi' -WindowStyle Hidden
                    Start-Process -FilePath "$env:windir\System32\sc.exe" -ArgumentList 'config mrxsmb10 start= disabled' -WindowStyle Hidden
                }
            }
        '^6\.(0|1).*'
            {
                # Windows Vista / Server 2008 / Windows 7 / Server 2008R2
                
                # SMB1 Server Settings
                if (((Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" -Name SMB1 -ErrorAction SilentlyContinue).SMB1) -ne '0') {
                    Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" -Name SMB1 -Type DWORD -Value 0 -Force -ErrorAction SilentlyContinue
                }


                # SMB1 Client Settings
                if ((sc.exe qc lanmanworkstation) -match 'MRxSmb10') {
                    Start-Process -FilePath "$env:windir\System32\sc.exe" -ArgumentList 'config lanmanworkstation depend= bowser/mrxsmb20/nsi' -WindowStyle Hidden
                    Start-Process -FilePath "$env:windir\System32\sc.exe" -ArgumentList 'config mrxsmb10 start= disabled' -WindowStyle Hidden
                }
            }
        default {
            Throw "Unsupported Operating System"
        }
    }


    Exit 0


} Catch {
    $LastError = $Error | Select-Object -First 1 -ExpandProperty Exception | Select-Object -ExpandProperty Message
    Write-Warning -Message $LastError
    Exit 1
}

The scripts are mostly identical, with the “detect” version simply returning true or false, and the “remediate” version actually modifying the settings if required.

Go to the Compliance Rules tab across the top and add a new rule.  Set a name (e.g. SMB1 Enabled) and set that the value returned from the script must equal False.  Check the box to run the specified remediation script if noncompliant, and set the noncompliance severity to whatever you’d like.  In my case I also wanted to report noncompliance if the value wasn’t returned (e.g. an error running the script).

Select OK, then Next.  This page is the Compliance Rules page (which we already defined), so select Next again to go to the Summary page, and Next to actually create the item.

Now that our configuration item is created, we’ll need to add this to a Configuration Baseline.  Select Configuration Baselines, and then Create Configuration Baseline.  Give it a name, description, and add your configuration item then select OK.

Deploy it to some test machines to ensure it works as expected (with whatever schedule you’d like for how often to check for compliance).  Assuming it does, you can then do a phased rollout to the rest of your machines monitoring for issues as you go.