How to Efficiently Configure Local LM Hash Storage Using PowerShell

Configuring Local LM Hash Storage plays a critical role in Windows-based systems. For IT professionals, the configuration of this storage can greatly affect system security. The PowerShell script provided elegantly simplifies the process of toggling this feature on or off. Let’s delve into its significance and how it functions.

Background

The LM hash, or LAN Manager hash, has been around for some time and is known for its vulnerabilities. Over time, many security practitioners have recommended disabling LM hashes to bolster system security. However, manual configurations can be tedious, which is why tools and scripts, like the one provided, become invaluable assets for IT professionals and Managed Service Providers (MSPs).

The Script

#Requires -Version 5.1

<#
.SYNOPSIS
    Disable or Enable Local LM Hash Storage
.DESCRIPTION
    Disable or Enable Local LM Hash Storage
.EXAMPLE
    -Enable
    Enable Local LM Hash Storage
.EXAMPLE
    -Disable
    Disable Local LM Hash Storage
.EXAMPLE
    PS C:> Disable-LMHash.ps1 -Disable
    Disable Local LM Hash Storage
.OUTPUTS
    None
.NOTES
    Minimum OS Architecture Supported: Windows 10, Windows Server 2016
    Release Notes:
    Initial Release
By using this script, you indicate your acceptance of the following legal terms as well as our Terms of Use at https://www.ninjaone.com/terms-of-use.
    Ownership Rights: NinjaOne owns and will continue to own all right, title, and interest in and to the script (including the copyright). NinjaOne is giving you a limited license to use the script in accordance with these legal terms. 
    Use Limitation: You may only use the script for your legitimate personal or internal business purposes, and you may not share the script with another party. 
    Republication Prohibition: Under no circumstances are you permitted to re-publish the script in any script library or website belonging to or under the control of any other software provider. 
    Warranty Disclaimer: The script is provided “as is” and “as available”, without warranty of any kind. NinjaOne makes no promise or guarantee that the script will be free from defects or that it will meet your specific needs or expectations. 
    Assumption of Risk: Your use of the script is at your own risk. You acknowledge that there are certain inherent risks in using the script, and you understand and assume each of those risks. 
    Waiver and Release: You will not hold NinjaOne responsible for any adverse or unintended consequences resulting from your use of the script, and you waive any legal or equitable rights or remedies you may have against NinjaOne relating to your use of the script. 
    EULA: If you are a NinjaOne customer, your use of the script is subject to the End User License Agreement applicable to you (EULA).
.COMPONENT
    ProtocolSecurity
#>

[CmdletBinding(DefaultParameterSetName = "Disable")]
param (
    [Parameter(Mandatory, ParameterSetName = "Disable")]
    [switch]
    $Disable,
    [Parameter(Mandatory, ParameterSetName = "Enable")]
    [switch]
    $Enable
)

begin {
    function Test-IsElevated {
        $id = [System.Security.Principal.WindowsIdentity]::GetCurrent()
        $p = New-Object System.Security.Principal.WindowsPrincipal($id)
        if ($p.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator))
        { Write-Output $true }
        else
        { Write-Output $false }
    }
    function Set-ItemProp {
        param (
            $Path,
            $Name,
            $Value,
            [ValidateSet("DWord", "QWord", "String", "ExpandedString", "Binary", "MultiString", "Unknown")]
            $PropertyType = "DWord"
        )
        New-Item -Path $Path -Force -ErrorAction SilentlyContinue | Out-Null
        if ((Get-ItemProperty -Path $Path -Name $Name -ErrorAction SilentlyContinue)) {
            Set-ItemProperty -Path $Path -Name $Name -Value $Value -Force -Confirm:$false | Out-Null
        }
        else {
            New-ItemProperty -Path $Path -Name $Name -Value $Value -PropertyType $PropertyType -Force -Confirm:$false | Out-Null
        }
    }
}
process {
    if (-not (Test-IsElevated)) {
        Write-Error -Message "Access Denied. Please run with Administrator privileges."
        exit 1
    }
    $Path = "HKLM:SYSTEMCurrentControlSetControlLsa"
    $Name = "NoLMHash"
    $Value = if ($Enable) { 1 }elseif ($Disable) { 0 }else { throw "No Param used." }
    # Sets NoLMHash to 1
    try {
        Set-ItemProp -Path $Path -Name $Name -Value $Value
    }
    catch {
        Write-Error $_
        exit 1
    }
    Write-Host "Set $Path$Name to $Value"
}
end {}

 

Access 300+ scripts in the NinjaOne Dojo

Get Access

Detailed Breakdown

The script begins by setting the requirements for PowerShell version 5.1. Here’s a step-by-step breakdown of its function:

  • Cmdlet Binding: The script uses CmdletBinding, allowing it to accept parameters, specifically -Enable or -Disable.
  • Test-IsElevated Function: This function checks if the script is running with elevated privileges (as an administrator). If not, the script will return an error.
  • Set-ItemProp Function: This function is designed to set a specified registry key with a given value, creating it if it doesn’t exist.
  • Process Block: This is where the main logic resides.
  • Checks for administrator rights.
  • Defines the registry path and name.
  • Depending on the parameter used (Enable or Disable), it assigns a value.
  • It then sets this value in the registry.
  • End Block: Concludes the script.

Potential Use Cases

Imagine an MSP that oversees security for multiple clients. One of their new onboarding procedures is to ensure that LM Hash Storage is disabled across all servers. Rather than manually updating each server’s settings, the MSP could deploy this script, efficiently making the changes and ensuring consistency.

Comparisons

Manually navigating through the registry or using Group Policy are other methods to achieve this result. However, using PowerShell is more efficient, especially when changes need to be made across numerous systems. Moreover, scripts are less prone to human error compared to manual methods.

FAQs

  • What does “NoLMHash” represent?
    The “NoLMHash” is a registry key that dictates whether LM Hashes are stored. A value of ‘0’ means it’s enabled, while ‘1’ means it’s disabled.
  • Can this script be run on any Windows system?
    The script has a noted minimum requirement: Windows 10 or Windows Server 2016 and above.

Implications

Configuring LM Hash Storage is not just a matter of operational efficiency—it’s a significant security consideration. LM hashes are notoriously insecure. Having a method to quickly and reliably disable these hashes can drastically reduce vulnerabilities.

Recommendations

  • Always backup the registry before making changes.
  • Periodically review and audit system configurations to ensure adherence to security best practices.
  • Only run scripts from trusted sources.

Final Thoughts

For IT professionals looking to simplify their tasks while maintaining a high level of security, leveraging powerful tools becomes crucial. This script is a testament to that capability. Furthermore, platforms like NinjaOne can enhance the process by centralizing and automating tasks related to system configuration and security. As the digital landscape evolves, having reliable tools and platforms at one’s disposal will be the key to maintaining a robust security posture.

Next Steps

Building an efficient and effective IT team requires a centralized solution that acts as your core service deliver tool. NinjaOne enables IT teams to monitor, manage, secure, and support all their devices, wherever they are, without the need for complex on-premises infrastructure.

Learn more about NinjaOne Remote Script Deployment, check out a live tour, or start your free trial of the NinjaOne platform.

Categories:

You might also like

×

See NinjaOne in action!

By submitting this form, I accept NinjaOne's privacy policy.

NinjaOne Terms & Conditions

By clicking the “I Accept” button below, you indicate your acceptance of the following legal terms as well as our Terms of Use:

  • Ownership Rights: NinjaOne owns and will continue to own all right, title, and interest in and to the script (including the copyright). NinjaOne is giving you a limited license to use the script in accordance with these legal terms.
  • Use Limitation: You may only use the script for your legitimate personal or internal business purposes, and you may not share the script with another party.
  • Republication Prohibition: Under no circumstances are you permitted to re-publish the script in any script library belonging to or under the control of any other software provider.
  • Warranty Disclaimer: The script is provided “as is” and “as available”, without warranty of any kind. NinjaOne makes no promise or guarantee that the script will be free from defects or that it will meet your specific needs or expectations.
  • Assumption of Risk: Your use of the script is at your own risk. You acknowledge that there are certain inherent risks in using the script, and you understand and assume each of those risks.
  • Waiver and Release: You will not hold NinjaOne responsible for any adverse or unintended consequences resulting from your use of the script, and you waive any legal or equitable rights or remedies you may have against NinjaOne relating to your use of the script.
  • EULA: If you are a NinjaOne customer, your use of the script is subject to the End User License Agreement applicable to you (EULA).