Easily work with BigFix APIs in PowerShell

is this module installed only on bigfix application server or any where,–> PS> Install-Module -Name BigFix

This is installed on the machine you wish to run any developed scripts on. Nothing needs to be installed on the server (unless you want to use the capabilities the module offers on the server).

Cool project, what would it take to make a remove device from bigfix powershell cmdlet?

The SOAP API is “read-only” since it actually work with the Web Report database.

I believe it would need to make use of the REST API to be able to “Mark a Computer as Deleted”.

any sample code for below things

How would be get the computer name with installed application list using powershell cmdlet,

1 Like

As @TimRice pointed out:

The SOAP API is “read-only” since it actually work with the Web Report database.

I believe it would need to make use of the REST API to be able to “Mark a Computer as Deleted”.

Currently, the module just speaks the SOAP API. REST API support is coming, but there are a few additional capabilities that have to be developed first (like the ability to treat content [actions/analyses/fixlets/tasks] as first-class objects vs .BES XML) to enable that.

You can however leverage the direct PowerShell commands do accomplish this if you want.

$Credential = Get-Credential
$ComputerId = "COMPUTER_ID_TO_DELETE"
Invoke-RestMethod -Uri "https://bigfix:52311/api/computer/$($ComputerId)" -Method Delete -Credential $Credential

If you leveraged New-WebReportsSession previously (say to query for the computer id to delete) and your Web Reports credentials are the same as your Console Operator account, you can replace the first line above with:

$Credential = (Get-WebReportsSession).Credential

Just keep in mind that error handling and the processing of the Invoke-RestMethod call are not shown and you should handle this.

1 Like

First, let me give warning. The Installed Windows Applications List property is NOT to be used without a degree of caution. It was created to be consumed by BigFix Inventory and as such, does not play well with casual data pulling. This property is in all likelihood the largest (in terms of data contained) property that exists within your environment (by several orders of magnitude) and depending upon the number of endpoints in your environment, may represent several GBs worth of data.

With that said, getting the data and actually using the data are two different topics for this property. Like any property, you can retrieve the results using standard session relevance.

First, establish a session with your Web Reports server:

PS> New-WebReportsSession -Uri <URL_TO_YOUR_WEBREPORTS_SERVER>

Now, evaluate your session relevance statement:

PS> $answer = Invoke-EvaluateSessionRelevance -Relevance '((if (exists names of it) then (name of it) else ("<not reported>")) of computer of it, values of it) of results of bes property "Installed Windows Applications List"' -FieldNames 'ComputerName', 'InstalledApplication'

If you explore $answer.Results, you will see your results:

ComputerName    InstalledApplication                                                                                                                                      
------------    ---------------------                                                                                                                                      
COMPUTER-001    <Key><Name>Adobe Flash Player ActiveX</Name><DisplayName>Adobe...
COMPUTER-001    <Key><Name>Adobe Flash Player NPAPI</Name><DisplayName>Adobe...

You get 1 record (row) for each Computer Name / Installed Application pair. As you can see, the Installed Windows Applications List property is not just normal text, but rather XML fragments (key here… fragments). We can clean this up a little to make it more PowerShell friendly:

PS> $answer.Results | Select-Object -Property ComputerName, @{ Label = 'App'; Expression={ ([xml]($_.InstalledApplication)).Key } } | Select-Object -Property ComputerName -ExpandProperty App

This will result in the much friendlier:

ComputerName    Name                                                                                           DisplayName                                                 
------------    ----                                                                                           -----------                                                 
COMPUTER-001 Adobe Flash Player ActiveX                                                                     Adobe Flash Player 32 ActiveX                               
COMPUTER-001 Adobe Flash Player NPAPI                                                                       Adobe Flash Player 32 NPAPI                                 

As you can see with just a couple of lines of PowerShell, the BigFix module, and a single session relevance expression even one of the most complicated to work with properties can be tamed with ease.

4 Likes

I am getting below error while run the command --> Install-Module -Name BigFix

Install-module : The term ‘Install-module’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try
again.

any help here

Looks like your running an older version of PowerShell.

You can follow the Microsoft installation instructions found at https://docs.microsoft.com/en-us/powershell/gallery/installing-psget.

2 Likes

I am using below version on windows 2012R2 server,

Major Minor Build Revision


4 0 -1 -1

is this suitable version,

Thanks,
Nagaraj,

It’s suitable… just <5.0 didn’t come with the PSGet module included by default. Just follow the instructions in the URL and you will be good

@MDMike Thanks for your work on this module. Very nice work!

Is there a graceful way to terminate the session? When I use the $session.Dissconnect() scriptmethod subsequent New-WebReportsSession tries fail out, until I kill the PSH shell that started the initial session.

If I could venture a 2nd question:

I’m passing a credential object to New-WebReportSession which gets me a session token. But when I Invoke-EvaluateSessionRelevance I get Invalid username or password. Same credential object is passed to both, but the username token combo fail. Any idea why?

Here’s the verbose output:

VERBOSE: Loading module from path 'C:\Program Files\WindowsPowerShell\Modules\BigFix\1.0\BigFix.psd1'.
VERBOSE: Loading 'FormatsToProcess' from path 'C:\Program Files\WindowsPowerShell\Modules\BigFix\1.0\BigFix.Format.ps1xml'.
VERBOSE: Populating RepositorySourceLocation property for module BigFix.
VERBOSE: Loading module from path 'C:\Program Files\WindowsPowerShell\Modules\BigFix\1.0\BigFix.psm1'.
VERBOSE: Exporting function 'Get-WebReportsServer'.
VERBOSE: Exporting function 'Get-WebReportsSession'.
VERBOSE: Exporting function 'Invoke-EvaluateSessionRelevance'.
VERBOSE: Exporting function 'New-WebReportsServer'.
VERBOSE: Exporting function 'New-WebReportsSession'.
VERBOSE: Exporting function 'Set-WebReportsServer'.
VERBOSE: Exporting function 'ParseStructuredResult'.
VERBOSE: Exporting function 'ParseInnerStructuredResult'.
VERBOSE: Exporting function 'Test-Uri'.
VERBOSE: Importing function 'Get-WebReportsServer'.
VERBOSE: Importing function 'Get-WebReportsSession'.
VERBOSE: Importing function 'Invoke-EvaluateSessionRelevance'.
VERBOSE: Importing function 'New-WebReportsServer'.
VERBOSE: Importing function 'New-WebReportsSession'.
VERBOSE: Importing function 'Set-WebReportsServer'. cmdlet Get-Credential at command pipeline position 1
Supply values for the following parameters:
VERBOSE: Test-Uri will be validating using UriKind 'Absolute'
VERBOSE: Test-Uri will be validating using UriKind 'Absolute'
VERBOSE: Test-Uri will be validating using UriKind 'Absolute'
VERBOSE: Obtaining Web Reports API service descriptor 'https://SCRUBBED.com/?wsdl'.
VERBOSE: Connecting to Web Reports Server: https://SCRUBBED.com/
VERBOSE: Evaluating Relevance: maximum of versions of modules
VERBOSE: Evaluation produced 1 answer(s) in 00:00:01.0162700.
VERBOSE: Connected to Web Reports Server: https://SCRUBBED.com/ (Version 9.5.13.130)
VERBOSE: Evaluating Relevance: number of bes computers
VERBOSE: Evaluation failed: Exception calling "GetStructuredRelevanceResult" with "1" argument(s): "Invalid username or password."

I’ll have to look into why disconnect is not working for you. There is a new release of the code base that adds local evaluation support and incorporates some other bug fixes that I will be uploading sometime this week. I’ll try to include fixes for the disconnect. Part of process when establishing the new session is to read in the SOAP WSDL document from the server and build the client stub from that. This process can sometimes cause issues due to the way that BigFix created their interface spec and limitations in the .NET framework capabilities. I may just end up creating a fixed client stub instead (although not ideal) to overcome that issue.

I don’t see the commands you called but can you confirm it was something like this:

PS> $Session2 = New-WebReportsSession -Uri ‘http://webreports/’ -Credential $Credential
PS> Invoke-EvaluateSessionRelevance -Relevance ‘number of bes computers’ -Session $Session2

It’s strange cause the New-WebReportsSession issues relevance to obtain the Web Reports Server version so that should have failed first, but based upon your output that was not the case.

Thanks for looking at this @MDMike. My script is exactly that, but of course I have included the -verbose flag at the end. (Removed and confirmed same behavior)

It looks like I am getting the version back in the example above (Version 9.5.13.130).

I can confirm that the following methods are being populated correctly:

$Session.Service.RequestHeaderElement.username
$Session.Service.RequestHeaderElement.sessionToken

I’ve also tried different wait times (zero, 5. 20, 30, 60 seconds) between New-WebReportsSessionand Invoke-EvaluateSessionRelevance.

I can confirm the user isn’t locked out in AD and shows 0 invalid attempts, despite this “Invalid username or password.” error. However, this error doesn’t show up in the BigFix server logs.

Fri, 23 Aug 2019 17:03:00 -0400 -- /soap (6456) --     User domain\user authenticated successfully
Fri, 23 Aug 2019 17:03:00 -0400 -- /soap (6456) --     Entering WebReportsRelevanceEvaluator::Evaluate( maximum of versions of modules )
Fri, 23 Aug 2019 17:03:00 -0400 -- PostAuditMessage (6240) -- Entering POST data/audit-message
Fri, 23 Aug 2019 17:03:00 -0400 -- /soap (6456) --     Exiting WebReportsRelevanceEvaluator::Evaluate( maximum of versions of modules ) (0 ms)
Fri, 23 Aug 2019 17:03:00 -0400 -- /soap (6456) --   Exiting SOAP Method: GetStructuredRelevanceResult (150 ms)
Fri, 23 Aug 2019 17:03:00 -0400 -- /soap (6456) -- Exiting ProcessSOAPRequest (466 ms)

My spidy senses tell me there’s either a user configuration I’m unaware of to enable SOAP for this user, or the module is sending a malformed request… Where is this error coming from if the server log doesn’t show it and AD shows no invalid auth attempts?

How difficult would it be for me to retool this to use “unstructured” RelevanceRequest?

Looking forward to the new version, thanks for your help!

The issue is not with the account or the structured relevance result. As your log shows (and the verbose output confirms), the “maximum of versions of modules” query that is executed to confirm the session is established executes without problems. Can you provide (direct message is fine if you don’t want to post publicly) your script so I can see exactly how your calling the functions? Also, if you run the following, does it work for you?

PS> $Session = New-WebReportsSession -Uri ‘http://webreports/’ -Debug
PS> Invoke-EvaluateSessionRelevance -Relevance ‘number of bes computers’ -Session $Session -Debug

No, running with -Debug doesn’t change the result. The script is super simple, here’s what I’m running:

$LoadedModules = Get-Module | ? {$_.name -like "*BigFix*"}
  if (!$LoadedModules) {
        Import-Module -Name $ModuleName
    }else{
        Write-Verbose "$($ModuleName) module already loaded"
    }
}

Check-LoadedModule BigFix -Verbose

if(!($credSoap)){
    $credSoap = Get-Credential
}

$Session = New-WebReportsSession -Uri 'https://SCRUBBED.com:443/soap'  -Credential $credSoap -Debug
Invoke-EvaluateSessionRelevance -Relevance ‘number of bes computers’ -Session $Session -Debug

Here’s the stdout:

VERBOSE: BigFix module already loaded
cmdlet Get-Credential at command pipeline position 1
Supply values for the following parameters:
DEBUG: Testing 'https://SCRUBBED.com:443/soap' is a well-formed URI of kind Absolute
DEBUG: Testing 'https://SCRUBBED.com:443/soap' is instantiatable
DEBUG: Testing 'https://SCRUBBED.com:443/soap' is a well-formed URI of kind Absolute
DEBUG: Testing 'https://SCRUBBED.com:443/soap' is instantiatable
DEBUG: Testing 'https://SCRUBBED.com:443/soap' is using an acceptable scheme
DEBUG: Uri 'https://SCRUBBED.com:443/soap' is NOT using the scheme 'http'
DEBUG: Uri 'https://SCRUBBED.com:443/soap' is using the scheme 'https'
DEBUG: Testing 'https://SCRUBBED.com:443/soap' is a well-formed URI of kind Absolute
DEBUG: Testing 'https://SCRUBBED.com:443/soap' is instantiatable

Relevance               Status Execution Time   Evaluation Time Result Count Result                                                                                                
---------               ------ --------------   --------------- ------------ ------                                                                                                
number of bes computers Error  00:00:00.4403260                 1            Exception calling "GetStructuredRelevanceResult" with "1" argument(s): "Invalid username or password." 

If it helps, I have a working RelevanceResult script using the same creds that follows this script:

<# https://gallery.technet.microsoft.com/scriptcenter/Soap-Request-Basic-adce2dcb
    Srinivasa Tumarada 
#> 
Function Soap_Request_Basicauth() 
{ 
Param ( 
            [Parameter(Mandatory=$True,ValueFromPipeline=$False,ValueFromPipelinebyPropertyName=$False)] 
            [xml]$SOAP_Request, 
            [Parameter(Mandatory=$True,ValueFromPipeline=$False,ValueFromPipelinebyPropertyName=$False)] 
            [String]$URL, 
            [Parameter(Mandatory=$True,ValueFromPipeline=$False,ValueFromPipelinebyPropertyName=$False)] 
            [string]$Uname, 
            [Parameter(Mandatory=$True,ValueFromPipeline=$False,ValueFromPipelinebyPropertyName=$False)] 
            [string]$Password 
    ) 
 
    Begin {  } 
 
    Process { 
     
    $SOAPRequest = $SOAP_Request 
     
    Write-host "Sending SOAP Request To Server: $URL" 
     
    $Soap_WebRequest = [System.Net.WebRequest]::Create($URL) 
     
    [string]$authInfo = $uname + ":" + $Password 
    [string]$authInfo = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($uname + ':' + $password)) 
    $Soap_webRequest.Headers.Add("AUTHORIZATION","Basic $authinfo") 
    $Soap_WebRequest.Headers.Add("SOAPAction","`"`"") 
    $Soap_WebRequest.ContentType = "text/xml;charset=`"utf-8`"" 
    $Soap_WebRequest.Accept      = "text/xml" 
    $Soap_WebRequest.Method      = "POST" 
 
    Write-host "Initiating Send." 
     
    $RequestStream = $soap_WebRequest.GetRequestStream() 
    $SOAPRequest.Save($requestStream) 
    $requestStream.Close() 
 
    Write-host "Soap Request sent, Waiting For Response." 
         
     $resp = $soap_WebRequest.GetResponse() 
     $responseStream = $resp.GetResponseStream() 
     $soapReader = [System.IO.StreamReader]($responseStream) 
     $ReturnXml = [Xml] $soapReader.ReadToEnd() 
     $responseStream.Close() 
 
     Write-host "Response Received." 
     } 
 
     End {  write-output $Returnxml } 
}

if(!($cred)){
    $cred = Get-Credential
}

$soap_object=[xml]((get-content -path "file.xml")) 
    $Response=(Soap_Request_Basicauth -uname $cred.username -password $cred.GetNetworkCredential().password -Soap_Request ($soap_object.Innerxml) -URL "https://SCRUBBED.com:443/soap") 
    $Status=($response.Envelope.Body.inboundResponse.return) 

    $Response.Envelope.Body.GetRelevanceResultResponse.a | Export-Clixml 'output.xml'

this is great information, do you know of a way to query the computer name instead of ID?

Not following. Are you asking how to use the REST API to get to the computer’s object https://bigfix:52311/api/computer/[COMPUTERID] but without knowing the [COMPUTERID]?

There is no direct path to so you must first query for the computer ID using the computer name like:

https://bigfix:52311/api/query?relevance=ids+of+bes+computers+whose+(name+of+it+is+"[COMPUTERNAME]")

You will then need to parse the response to extract the ID.

thank you for the information, I am trying to automate removing of the bigfix entry upon a user leaving the company using powershell. I am fairly new to powershell, so still in the process of learning what it can do.

thanks for your help.

New-WebReportsSession : Cannot validate argument on parameter ‘Uri’. The term ‘Test-Uri’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path i
s correct and try again.

getting this error=\

@MDMike