Quantcast
Channel: Microsoft – JeffOps
Viewing all articles
Browse latest Browse all 120

Get remote Best Practice Analyzer results through PowerShell

$
0
0

Today I received an email from a community member where he wrote that he was writing a PowerShell script that basically does the same thing at the Microsoft Best Practice Analyzer.
Why? Couldn’t you just use the BPA to do all the work for you? The answer is both yes and no…

The BestPractices cmdlets don’t have a -ComputerName parameter, so no native remoting in them.
Because of this I’ve chosen to use PowerShell remoting to execute the BestPractices cmdlets on the remote device, but as it seems some checks see that they are invoked remotely and provide you the message that they won’t work:

The following nodes in a failover cluster cannot be verified because the nodes are not reachable, 
or because the BPA scan was performed against a remote failover cluster: server1,server2,server3,server4

#RANT
Kind to give a message stating this, but that isn’t very nice! So, one can’t execute all tests remotely?
When you use PowerShell remoting, the command is actually executed on the remote device as if you where actually sitting at the device.
So why the h*ll would that be a problem?
I can’t answer that one… :-(
#END RANT

Anywayz, back on topic.
Getting the results is a two-step process.
First you have to execute the BPA. Secondly, when the first is done, you can get the results.
To get kick off the BPA, I’ve written the following function:

function Invoke-BPA {
    param (
        [parameter(mandatory=$false,position=1)][array]$ComputerName=$Env:ComputerName
    )
    begin {
        $Session = New-PSSession -ComputerName $ComputerName
    } process {
        $ComputerName | foreach { 
            Invoke-Command -ComputerName $_ -ScriptBlock { 
                import-module bestpractices; foreach ($BPAModel in (Get-BpaModel)) { 
                    Invoke-BpaModel -BestPracticesModelId $BPAModel.ID 
                }
            }
        } | out-null
    } end {
        Remove-PSSession $Session
    }
}

Next up will be to get the results. The following function allows you to do this:

function Get-BPA {
    param (
        [parameter(mandatory=$false,position=1)][array]$ComputerName=$Env:ComputerName
    )
    begin {
        $Session = New-PSSession -ComputerName $ComputerName
    } process {
        $ComputerName | foreach { 
            invoke-command -ComputerName $_ -ScriptBlock { 
                Import-Module bestpractices; foreach ($BPAModel in (Get-BPAModel)) { 
                    Get-BpaResult -BestPracticesModelId $BPAModel.ID | 
                    Where-Object {($_.Severity -ne 'Information') -and ($_.Problem -notlike '*or because the BPA scan was performed against a remote*')} | foreach {
                        $Object = New-Object -TypeName PSObject
                        $Object | Add-Member -MemberType NoteProperty -Name 'Title' -Value $_.Title
                        $Object | Add-Member -MemberType NoteProperty -Name 'Severity' -Value $_.Severity
                        $Object | Add-Member -MemberType NoteProperty -Name 'Category' -Value $_.Category
                        $Object | Add-Member -MemberType NoteProperty -Name 'Problem' -Value $_.Problem
                        $Object | Add-Member -MemberType NoteProperty -Name 'Impact' -Value $_.Impact
                        $Object | Add-Member -MemberType NoteProperty -Name 'Resolution' -Value $_.Resolution
                        $Object
                    }
                }
            }
        }
    } end {
        Remove-PSSession $Session
    }    
}

Please note that since this is part of a rather large script I’ve been working on, I have chosen not to make the second function dependable on wether or not the tasks the first functions executes are finished or not. So, the second function doesn’t wait for the BPA to be executed…

But… because I use PowerShell remoting an extra property gets attached, namely the PSComputerName property.
Since I don’t want to see ‘PSComputerName’ but just ‘ComputerName’ (without the PS).
You can easily solve this by customizing the name of the expression, when you call the function:

Get-BPA -ComputerName 'server1','server2' | select Title,Severity,Category,Problem,Impact,Resolution,@{Name='ComputerName';Expression={$_.PSComputerName}}

Viewing all articles
Browse latest Browse all 120

Trending Articles