locked
Script to get Registry key value from all server in AD and output to csv RRS feed

  • Question

  • Hi,

    I'm looking for some help with a script to get a csv output of a registry value from all of our servers in AD. The script below is good but it does work properly if the registry value or key does not exist in the computer registry. So how do i get the script to work and output the server name if they don't have this registry key. 

    Import-Module ActiveDirectory

    # No need for the Select-Object here since we're using $SRV.Name later
    $SRVS = Get-ADComputer -Filter * -SearchBase 'DC=abcd,DC=abcd,DC=com'

    # Create an arraylist to save our records
    $Report = New-Object System.Collections.ArrayList

    # This try finally is to ensure we can always write out what we've done so far
    try {
        foreach ($SRV in $SRVS) {
            # Test if the remote computer is online
            $IsOnline = Test-Connection -ComputerName $SRV.Name -Count 1 -Quiet;
            if ($IsOnline) {
                # If system is Online
                $REG = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $SRV.name)
                $REGKEY = $REG.OpenSubKey("HKLM:\SYSTEM\CurrentControlSet\services\LanmanServer\Parameters")
                $MELT = $REGKEY.GetValue('SMB1')

                # Create a PSObject record for convenience
                $Record = [PSCustomObject]@{
                    ComputerName = $SRV;
                    Key          = $REGKEY.Name;
                    Value        = $MELT;
                }
            }
            else {
                # If system is Offline
                # Create a PSObject record for convenience
                $Record = [PSCustomObject]@{
                    ComputerName = $SRV;
                    Key          = '';
                    Value        = '';
                }
            }

            # Add our record to the report
            $Report.Add($Record);
        }
    }
    finally {
        # Always write out what we have whether or not we hit an error in the middle
        $Report | Export-Csv -Path "C:\temp\output.csv" -NoTypeInformation
    }

    Monday, May 20, 2019 1:04 PM

All replies

  • You'd probably want to wrap your code in another try/catch:

    # If system is Online
    try{
        $REG = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $SRV.name)
        $REGKEY = $REG.OpenSubKey("HKLM:\SYSTEM\CurrentControlSet\services\LanmanServer\Parameters")
        $MELT = $REGKEY.GetValue('SMB1')
    
        # Create a PSObject record for convenience
        $Record = [PSCustomObject]@{
            ComputerName = $SRV
            Key          = $REGKEY.Name
            Value        = $MELT
        }
    }
    Catch{
        # some code here to either record the failure or just do nothing
        # maybe something like this?
    
        # If reg key is missing
        # Create a PSObject record for convenience
        $Record = [PSCustomObject]@{
            ComputerName = $SRV
            Key          = 'NOT PRESENT'
            Value        = 'NOT PRESENT'
        }
    }

    P.S. You don't need the semi-colons as terminators inside the creation of the hashs.


    --- Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)

    • Proposed as answer by jrv Monday, May 20, 2019 6:54 PM
    Monday, May 20, 2019 3:00 PM
  • Thank you for your help. I modified the script to the following and now i'm getting the error for a call method on a null-valued expression. I think it's because the registry key SMB1 is missinf from the server and it's throwing that error. But the whole point of the script is to get a list of servers without this registry key.

    Import-Module ActiveDirectory

    # No need for the Select-Object here since we're using $SRV.Name later
    $SRVS = Get-ADComputer -Filter * -SearchBase 'DC=123,DC=abc,DC=com'

    # Create an arraylist to save our records
    $Report = New-Object System.Collections.ArrayList

    # This try finally is to ensure we can always write out what we've done so far
    try {
        foreach ($SRV in $SRVS) {
            # Test if the remote computer is online
            $IsOnline = Test-Connection -ComputerName $SRV.Name -Count 1 -Quiet;
            if ($IsOnline) {
                # If system is Online
                $REG = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $SRV.name)
                $REGKEY = $REG.OpenSubKey("HKLM:\SYSTEM\CurrentControlSet\services\LanmanServer\Parameters")
                $MELT = $REGKEY.GetValue('SMB1')

                # Create a PSObject record for convenience
                $Record = [PSCustomObject]@{
                    ComputerName = $SRV;
                    Key          = $REGKEY.Name;
                    Value        = $MELT;
                }
            }
            Catch{ 
                # If reg key is missing
            # Create a PSObject record for convenience
                $Record = [PSCustomObject]@{
            ComputerName = $SRV
            Key          = 'NOT PRESENT'
            Value        = 'NOT PRESENT'
                }
            }

            # Add our record to the report
            $Report.Add($Record);
        }
    }
    finally {
        # Always write out what we have whether or not we hit an error in the middle
        $Report | Export-Csv -Path "E:\Utils\jsc.csv" -NoTypeInformation
    }

    Monday, May 20, 2019 5:44 PM
  • That code is missing the 1st "try" in my suggested change. . . the one right after the "# If system is Online" line in your code.

    --- Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)


    Monday, May 20, 2019 6:01 PM
  • Oh i missed that part. Here's the completed script...is this correct? I'm still getting the null-valused expression error. It seems like whenever a server don't have the registry key "SMB1" then the script with error out.

    Import-Module ActiveDirectory

    # No need for the Select-Object here since we're using $SRV.Name later
    $SRVS = Get-ADComputer -Filter * -SearchBase 'DC=abc,DC=def,DC=com'

    # Create an arraylist to save our records
    $Report = New-Object System.Collections.ArrayList

    # This try finally is to ensure we can always write out what we've done so far
    try {
        foreach ($SRV in $SRVS) {
            # Test if the remote computer is online
            $IsOnline = Test-Connection -ComputerName $SRV.Name -Count 1 -Quiet;
            if ($IsOnline) {
                # If system is Online
                $REG = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $SRV.name)
                $REGKEY = $REG.OpenSubKey("HKLM:\SYSTEM\CurrentControlSet\services\LanmanServer\Parameters")
                $MELT = $REGKEY.GetValue('SMB1')

                # Create a PSObject record for convenience
                $Record = [PSCustomObject]@{
                    ComputerName = $SRV;
                    Key          = $REGKEY.Name;
                    Value        = $MELT;
                }
            }
           catch {
                # If system is Offline
                # Create a PSObject record for convenience
                $Record = [PSCustomObject]@{
                    ComputerName = $SRV;
                    Key          = 'Not Present'
                    Value        = 'Not Present'
                }
            }

            # Add our record to the report
            $Report.Add($Record);
        }
    }
    finally {
        # Always write out what we have whether or not we hit an error in the middle
        $Report | Export-Csv -Path "E:\Utils\jsc.csv" -NoTypeInformation
    }

    Monday, May 20, 2019 6:51 PM
  • No, it isn't correct. You're still missing the "Try{...}"

    --- Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)

    Monday, May 20, 2019 9:18 PM
  • Try this:

    $SRVS = Get-ADComputer -Filter "OperatingSystem -like 'Windows *Server*'" -SearchBase "DC=abc,DC=def,DC=com" | Select-Object -ExpandProperty Name | Sort-Object
    
    $Report = New-Object System.Collections.ArrayList
    
    $i = 0
    
    ForEach ($SRV in $SRVS) {
        
        $i++
        Write-Progress -Activity "Checking server registry for SMB v1..." -Status "Scanning: $SRV - $i of $($SRVS.Count)" -PercentComplete (($i/$SRVS.Count)*100)
    
        If (Test-Connection -ComputerName $SRV -Count 1 -Quiet) {
    
            Try {
    
                $Output = Invoke-Command -ComputerName $SRV -ScriptBlock {Get-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\services\LanmanServer\Parameters} -ErrorAction Stop
            
                If ($Output.SMB1) {
                
                    $Record = [PSCustomObject]@{
                            ComputerName = $SRV
                            Key          = "SMB1"
                            Value        = "Disabled"
    
                    }
    
                }
    
                Else {
    
                    $Record = [PSCustomObject]@{
                            ComputerName = $SRV
                            Key          = "SMB1"
                            Value        = "Enabled"
                    
                    }
    
                }
    
            }
    
            Catch {
    
                Try {
                
                    $Output = Invoke-Command -ComputerName $SRV -ScriptBlock {Get-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\services\LanmanServer\Parameters} -SessionOption (New-PSSessionOption -IncludePortInSPN) -ErrorAction Stop
                
                    If ($Output.SMB1) {
                    
                        $Record = [PSCustomObject]@{
                                ComputerName = $SRV
                                Key          = "SMB1"
                                Value        = "Disabled"
                
                        }
                
                    }
                
                    Else {
                
                        $Record = [PSCustomObject]@{
                                ComputerName = $SRV
                                Key          = "SMB1"
                                Value        = "Enabled"
                        
                        }
                
                    }
                
                }
                
                Catch {
    
                    $Record = [PSCustomObject]@{
                        ComputerName = $SRV
                        Key          = ""
                        Value        = "Cannot connect to registry"
    
                    }
    
                }
    
            }
        }
    
        Else {
    
            $Record = [PSCustomObject]@{
                ComputerName = $SRV
                Key          = ""
                Value        = "Cannot connect to server"
    
            }
    
        }
    
        $Report.Add($Record) | Out-Null
    
    }
    
    $Report | Export-Csv -Path "E:\Utils\jsc.csv" -NoTypeInformation

    • Proposed as answer by Simon Cutting Tuesday, May 21, 2019 3:54 PM
    Tuesday, May 21, 2019 3:53 PM
  • A word of caution here . . .

    The mere presence of the registry value "SMB1" is not an indication of SMB1 being enabled or disabled. If the SMB1 value is absent, SMB1 is enabled. If the SMB1 value is present and its value is "0", it's disabled. However, if the SMB1 value is "1" it's enabled.

    Your code makes an enabled/disabled decision incorrectly.

    https://support.microsoft.com/en-us/help/2696547/detect-enable-disable-smbv1-smbv2-smbv3-in-windows-and-windows-server


    --- Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)




    Tuesday, May 21, 2019 6:45 PM
  • Hi,

    Was your issue resolved?

    If you resolved it using our solution, please "mark it as answer" to help other community members find the helpful reply quickly.

    If you resolve it using your own solution, please share your experience and solution here. It will be very beneficial for other community members who have similar questions.

    If no, please reply and tell us the current situation in order to provide further help.

    Best Regards,

    Lee


    Just do it.

    Monday, June 3, 2019 7:47 AM