SnapManager for SharePoint Security Scan (Part 1)

One of the biggest issues faced when implementing NetApp SnapManager for SharePoint (SMSP) is ensuring that all the various permissions are setup properly. The permission requirements are quite intricate because of the fact we are dealing with Microsoft SharePoint Server and all of it's components (eg. Microsoft SQL Server, Web Front-End servers, Application Servers, Search, etc.) and then adding on top of this are the different requirements for SMSP Agents, Manager, database permissions, local system permissions, registry permissions, and more.

 

All of the permissions I am verifying can be found on what I consider the most important pages of the SMSP 7.1 Installation Guide:

  • Page 6: This details all the different ports that need to be enabled.
  • Pages 23 - 29: These pages detail all of the different SQL Server, SharePoint and system permissions that need to be set.
  • Page 47 - 48: These pages detail the Local System permissions that need to be set.

 

To help figure out all of the different permissions and what was set or not I started writing a PowerShell script that can be customized to check requirements for SMSP to run properly. As this blog entry title indicates this is Part 1 in a multiple part blog. The first scans I implemented were for all the different servers in a SharePoint Farm to ensure that the different groups had the proper accounts in them. This script does not check the account name but rather provides a report of the different groups that SMSP expects to have an account located that you use for the SMSP Service Account(s). In the example output below you can see an account I setup in my test farm called spfarm and the different groups that it is a member of; for this test I used one generic account for all my services but in the real world you can expect to have multiple accounts following the Least Privileged model for security. I took the report approach so administrators could see their current settings and then change them as appropriate in accordance with organizational policies. You can also see at the bottom of the example output some of the details related to the registry permissions checking.

There are two functions that are pretty self-explanatory; (1) ScanGroupsforMembers - which looks at the specific groups on the different servers in the farm and lists out all the members in those groups; and (2) CheckRegistryPermissions - installation of SMSP takes care of this but figured it should be added in order to provide a full scan.

 

function ScanGroupsforMembers {

    [CmdletBinding()]

    param(

        [Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true)]

        [ValidateNotNullOrEmpty()]

        [System.Management.Automation.PSObject]

        $InputObject

    )

    begin {

        $pipelineInput = -not $PSBoundParameters.ContainsKey('InputObject')

        $index = 1

    }

    process {

        if ($pipelineInput) {

            Write-Host "You need to specify servers."

        } else {

            $i=0

            foreach ($machine in $InputObject) {

                $machine = [ADSI]"WinNT://$machine"

                Write-Host

                Write-Host "================================"

                Write-Host $machine.Path

                Write-Host "================================"

 

                $groups = $machine.psbase.Children | Where {$_.psbase.schemaClassName -eq "group"}

                foreach ($group in $groups)

                {

                    Write-Progress -Activity "Getting Groups and Members" -Status "Progress" -PercentComplete ($i/10)

                    if ($group.name -eq "Administrators" -or `

                        $group.name -eq "Performance Monitor Users" -or `

                        $group.name -eq "WSS_WPG" -or `

                        $group.name -eq "IIS_IUSRS" -or`

                        $group.name -eq "WSS_ADMIN_WPG" -or `

                        $group.name -eq "DocAve Users")

                    {

                        "Group: " + $group.name

                        $users = @($group.psbase.Invoke("Members"))

                        foreach ($user in $users)

                        {

                            $class = $user.GetType().InvokeMember("Class", 'GetProperty', $null, $user, $null)

                            $name = $user.GetType().InvokeMember("Name", 'GetProperty', $null, $user, $null)

                            "-- Member: $name ($class)"

                        }

                    }

                    $i++

                }

          

            }

        }

    }

}

 

function CheckRegistryPermissions {

    [CmdletBinding()]

    param(

        [Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true)]

        [ValidateNotNullOrEmpty()]

         $InputObject

    )

    begin {

        $pipelineInput = -not $PSBoundParameters.ContainsKey('InputObject')

        $index = 1

    }

    process {

        if ($pipelineInput) {

            Write-Host "No implemeted."

        } else {

            foreach ($machine in $InputObject) {

                Write-Host

                Write-Host "==============================================================="

                Write-Host $machine

                Write-Host "==============================================================="

                Write-Host " HKLM:\SOFTWARE\Network Appliance\SnapManager for SharePoint 7"

                Write-Host "==============================================================="

                Invoke-Command -ComputerName $machine -ScriptBlock {(Get-Acl -Path 'HKLM:\SOFTWARE\Network Appliance\SnapManager for SharePoint 7').AccessToString}

                Write-Host "==============================================================="

                Write-Host " HKLM:\System\CurrentControlSet\Services\eventlog"

                Write-Host "==============================================================="

                Invoke-Command -ComputerName $machine -ScriptBlock {(Get-Acl -Path 'HKLM:\System\CurrentControlSet\Services\eventlog').AccessToString}

            }

        }

    }

}

 

#

# Different servers in my SharePoint Farm. This is expandable by just creating additional variables and then added those

# to be passed into the different functions.

#

$APPSERVER1 = 'APPMED1'

$SQLSERVER1 = 'SQL1'

$WFE1 = 'WFE1'

$WFE2 = 'WFE2'

 

# Clear!

cls

ScanGroupsforMembers($WFE1, $WFE2, $SQLSERVER1, $APPSERVER1)

CheckRegistryPermissions($WFE1, $WFE2, $SQLSERVER1, $APPSERVER1)

 

Next week I'll be adding the Microsoft SQL Server permissions checking, stay tuned.

 

Last post before the long weekend, l8r!

Barkz (aka NaSharePointGuy)