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.

Join the conversation

34 Comments

  1. Considering that Windows 10 and other new OS’es have smbv1 enabled by default, an automated solution, like the above is a must.
    However, I do not have SCCM, so could you detail out a powershell script that works via a GPO logon script that will do the job? I’ve been trying but my powershell fu is not good.

    1. You’d have to use a startup script (not a logon based one), as the commands would require elevation and logon scripts run in the users’ context. Alternatively you could use a scheduled task preference in the computer branch running as the system user, and just have it call the script. The remediation script should be all you need as it only performs the task if SMBv1 is enabled anyway.

      In the program you’d have : %windir%\System32\WindowsPowerShell\v1.0\powershell.exe
      In the arguments you’d have something like this: -NonInteractive -ExecutionPolicy Bypass -File \\*******\SysVol\******\Policies\{76E1059E-A962-4EC8-A0C7-5E76E78CD7FA}\Machine\Scripts\Startup\DisableSMBv1.ps1

      You may want to add a line in the PowerShell script (at the top) to delete the scheduled task so that it only runs once:
      Start-Process -FilePath $env:SystemRoot\System32\schtasks.exe -ArgumentList “/delete /tn `”YOUR TASK NAME GOES HERE`” /F” -NoNewWindow -ErrorAction SilentlyContinue

      For a trigger I’d just set it to be on task creation so that when Group Policy refreshes, the task is created and ran.

      Hope that helps!

  2. Hi,

    script doesn’t work on Windows Server 2012 since it doesn’t have an optional feature smb1protocol

    PS C:\Windows\system32> Get-WindowsOptionalFeature -Online | where Featurename -Like smb*

    Feature Name : SMBHashGeneration
    State : Disabled

    Feature Name : SmbDirect
    State : Enabled

    Feature Name : SmbWitness
    State : Disabled

    I guess script to detect should use:
    Get-SmbServerConfiguration | Select EnableSMB1Protocol

    Script to disable should use:
    Set-SmbServerConfiguration -EnableSMB1Protocol $false

    Otherwise very useful scripts these days 🙂
    Thank you!!!

    Best regards,
    Rok B

    1. Much appreciated for pointing that out! I’ve updated the scripts (and also took the opportunity to add Vista/Server 2008).

  3. When running the above scripts as is I got error on my windows 10 test machine, as “script is not signed”

    1. Hi Samer, that makes sense when trying to run manually. You’ll either need to set your execution policy to unrestricted or run it with “bypass”, or unblock the script if your policy is set to RemoteSigned. Hope that helps!

      1. Setting the Execution Policy for PowerShell to Bypass can be done in the client settings by going into the SCCM Console -> Administration -> Client Settings -> -> Computer Agent -> PowerShell execution policy and set it to bypass.

    1. You can view the status of the deployment in SCCM and it will show you the compliant and non-compliant devices.

  4. I’ve a Server 2012 R2 file server which is refusing to start the DFS Namespace or Server service after a reboot. Any tips on how I can reset this? Thanks.

      1. Best guess is that the service dependencies still have SMBv1 defined. Did you run the script or just disabled it manually. Try running the code for Windows 7 (the sc.exe portion as that defines the service to not require SMBv1). I’ll check to see if there are any other services that registered a dependency although Microsoft didn’t indicate as such in their instructions for disabling it.

      2. Sorry for the delayed response. I checked the servers I had available to me, and I can see that the DFS Namespace service has a dependency on the “Server” service so the issue is definitely there. Interestingly enough, I checked the dependencies on that, and even with SMB1 enabled, it wasn’t listed as a requirement. I ran my script to disable SMB1 and the Server service (and DFS Namespace service) both started fine on restart. For now where I’d start is looking at the dependencies of your Server service.

        1. Many thanks for getting back to me on this. I used your scripts with SCCM to detect and remediate. The System log errors showed:

          Event 7003: The Server service depends on the following service: Srv. This service might not be installed.

          Event 7001: The Browser service depends on the Server service which failed to start because of the following error: The dependency service does not exist or has been marked for deletion.

          1. Any chance you disabled SMBv2/3 in the past? I’ll take another look today but just curious if you did. If so, after disabling v1 you’d have nothing left.

          2. A colleague had the same issue as me and determined that lanmanserver was still looking for mrxsmb10. To fix this, he did the following. Please note, I haven’t been able to confirm this in my situation, but this seems reasonable; unless anyone can see a problem?

            REG ADD HKLM\SYSTEM\CurrentControlSet\services\LanmanServer\Parameters /v SMB1 /t REG_DWORD /d 0 /f
            REG ADD HKLM\SYSTEM\CurrentControlSet\services\LanmanWorkstation\Parameters /v SMB1 /t REG_DWORD /d 0 /f

            sc.exe config lanmanserver depend= samss/srv2
            sc.exe config lanmanworkstation depend= bowser/mrxsmb20/nsi

            sc.exe config mrxsmb10 start= disabled
            sc.exe config mrxsmb start= auto
            sc.exe config mrxsmb20 start= auto

            sc.exe config srv start= disabled
            sc.exe config srv2 start= auto

            net stop server
            net stop mrxsmb10
            net stop srv

            net start mrxsmb20
            net start srv2
            net start server

          3. Yes I would expect the same as your colleague. You could try the two sc.exe lines for the Windows 7/8 clients as a quicker method but what you outlined appears to fully configure those services.

            The part I’m definitely interested in though is how that happened. I tested on Server 2012R2 and 2012 multiple times and couldn’t replicate that scenario. Anyway, hope it works for you!

    1. Check my other comment. I’ll check one of my servers this morning to see if I can find any other dependencies.

        1. Hi Bill, I posted a response under the other comment so you may or may not be notified. In short, I ran my scripts again against a Server 2012 R2 box and had no issues with the Server or DFS Namespace service. Server is a required service for DFS Namespace, so I recommended looking at the dependencies to see if there was something in there that may be causing the issue. SMB1 wasn’t listed as a dependency in my case (even when it was installed), so perhaps something third party? There may be more information in the event logs as well as to what caused the service to crash.

  5. I’m an SCCM noobie but I managed to get this going on two test collections. The problem is all the devices are staying non-compliant.
    How do I figure why the remediation script isn’t firing?
    Thanks for the help!

    1. Hi Ryan,
      When you deploy it you have to check the box to remediate noncompliant rules when supported. You can open up the properties of your deployment and check that without deploying again.

  6. Lookslike it didn’t work for me. I tested on a collection of computers (Mostly Windows 10 and 1 Windows 7). They are show as Unknown in SCCM 2012 and on the PC itself SMBv1 still not disabled. Not sure why its not working on my environment even though I followed the exact same steps and double checked it too. Anything else I can check on?

    1. Make sure you have the PowerShell execution policy set to bypass in client settings. If you don’t the script may not run.

  7. Hi, having problems using sccm as it wants to use port 445 yet that port is blocked by AV. What alternative port can I force SCCM to use. Trying to use SCCM to update my servers.
    Thanks.

    1. I’m not sure I understand your question. This is just disabling SMBv1 so SMB would still be enabled, albeit only for Vista and later clients.

  8. Hi Kyle, thank you for this script!

    I’ve made a small modification for Windows 7 etc., because this part didn’t work when the Registry Value SMB1 does not exist at all. I’ve added a check to see if the Value exist:

    # 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’ -and (Get-Item -Path ‘HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters’).GetValue(‘SMB1’) -ne $null) -or ((sc.exe qc lanmanworkstation) -match ‘MRxSMb10’))

    Best regards!
    Rolf

    1. Hi Rolf, I’ll test that section again and update it with your suggestion. Thanks for the heads up!

Leave a comment

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.