├── .gitignore ├── BigFix ├── BigFix.Format.ps1xml ├── BigFix.Prepare.ps1 ├── BigFix.psd1 ├── BigFix.psm1 ├── Lib │ └── QnaSessionManager.cs ├── Private │ ├── Expand-StructuredRelevanceResult.ps1 │ └── Test-Uri.ps1 └── Public │ ├── Get-QnaSession.ps1 │ ├── Get-WebReportsServer.ps1 │ ├── Get-WebReportsSession.ps1 │ ├── Invoke-EvaluateClientRelevance.ps1 │ ├── Invoke-EvaluateSessionRelevance.ps1 │ ├── New-QnaSession.ps1 │ ├── New-WebReportsServer.ps1 │ ├── New-WebReportsSession.ps1 │ └── Set-WebReportsServer.ps1 ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # IDE - VSCode 2 | .vscode/* 3 | 4 | # System Files 5 | .DS_Store 6 | .Thumbs.db -------------------------------------------------------------------------------- /BigFix/BigFix.Format.ps1xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Server 6 | 7 | BigFix.WebReports.Server 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | Uri 18 | Wsdl 19 | 20 | 21 | 22 | 23 | 24 | 25 | Session 26 | 27 | BigFix.WebReports.Session 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | if ($_.Server) { $_.Server.Uri } else { '' } 41 | 42 | 43 | State 44 | 45 | 46 | if ($_.Credential -and $_.Credential.UserName) { $_.Credential.UserName } else { '' } 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | SessionRelevanceResult 56 | 57 | BigFix.SessionRelevanceResult 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | Relevance 72 | 73 | 74 | if ($_.Error) { 'Error' } else { 'Success' } 75 | 76 | 77 | Time 78 | 79 | 80 | if ($_.EvaluationTime) { [TimeSpan]::FromMilliseconds($_.EvaluationTime) } else { '' } 81 | 82 | 83 | 84 | 85 | if (@($_.Results).Count) { @($_.Results).Count.ToString('N0') } else { 0 } 86 | 87 | 88 | 89 | 90 | if ($_.Error) { $_.Error } else { @($_.Results) } 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /BigFix/BigFix.Prepare.ps1: -------------------------------------------------------------------------------- 1 | # Get the library type definitions 2 | $Libs = @(Get-ChildItem -Path $PSScriptRoot\Lib\*.cs -ErrorAction SilentlyContinue) 3 | 4 | # Add the library type definitions 5 | foreach ($file in @($Libs)) { 6 | try { 7 | Add-Type -TypeDefinition (Get-Content $file.FullName -Encoding UTF8 -Raw) 8 | } 9 | catch { 10 | throw "Failed to load library type definition(s) from '$($file.FullName)': $_" 11 | } 12 | } -------------------------------------------------------------------------------- /BigFix/BigFix.psd1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/promptussoftware/bigfix-powershell/acc196189bca68f264842af4b14017a020e0b7f5/BigFix/BigFix.psd1 -------------------------------------------------------------------------------- /BigFix/BigFix.psm1: -------------------------------------------------------------------------------- 1 | #Requires -Version 3.0 2 | 3 | # Get the public and private function definitions 4 | $Public = @( Get-ChildItem -Path $PSScriptRoot\Public\*.ps1 -Exclude *.tests.ps1, *profile.ps1 -ErrorAction SilentlyContinue ) 5 | $Private = @( Get-ChildItem -Path $PSScriptRoot\Private\*.ps1 -Exclude *.tests.ps1, *profile.ps1 -ErrorAction SilentlyContinue ) 6 | 7 | # Dot source the function definition files 8 | Foreach ($file in @($Public + $Private)) { 9 | Try { 10 | . $file.FullName 11 | } 12 | Catch { 13 | Write-Error -Message "Failed to import function definition(s) from '$($file.FullName)': $_" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /BigFix/Lib/QnaSessionManager.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Win32; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel; 5 | using System.Diagnostics; 6 | using System.IO; 7 | using System.Linq; 8 | using System.Management.Automation; 9 | using System.Security.Cryptography; 10 | using System.Threading.Tasks; 11 | using System.Text; 12 | 13 | namespace BigFix.Qna 14 | { 15 | public class Result 16 | { 17 | private string _hash = null; 18 | 19 | public string Relevance { get; private set; } 20 | public string[] Answer { get; private set; } 21 | public string Error { get; private set; } 22 | public long EvalTime { get; private set; } 23 | 24 | bool IsError { get { return this.Error != null; } } 25 | 26 | public Result(string Relevance, string[] Answer, string Error, long EvalTime) 27 | { 28 | this.Relevance = Relevance; 29 | this.Answer = Answer; 30 | this.Error = Error; 31 | this.EvalTime = EvalTime; 32 | } 33 | 34 | public string GetHash() 35 | { 36 | if (this._hash == null) 37 | { 38 | using (SHA256 hashAlgorithm = SHA256.Create()) 39 | { 40 | byte[] hash = hashAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(this.Relevance)); 41 | 42 | StringBuilder hashString = new StringBuilder(); 43 | 44 | for (int i = 0; i < hash.Length; i++) 45 | { 46 | hashString.Append(hash[i].ToString("x2")); 47 | } 48 | 49 | this._hash = hashString.ToString(); 50 | } 51 | } 52 | 53 | return this._hash; 54 | } 55 | 56 | public override string ToString() 57 | { 58 | StringBuilder output = new StringBuilder(); 59 | output.AppendFormat("Q: {0}\n", Relevance); 60 | foreach (string answer in Answer) 61 | { 62 | output.AppendFormat("A: {0}\n", answer); 63 | } 64 | if (IsError) 65 | { 66 | output.AppendFormat("E: {0}\n", Error); 67 | } 68 | output.AppendFormat("T: {0}\n", TimeSpan.FromMilliseconds(EvalTime)); 69 | 70 | return output.ToString(); 71 | } 72 | } 73 | 74 | public class Session : IDisposable 75 | { 76 | /// 77 | /// Default name of an environmental variable that can be set to define the location 78 | /// where the BigFix QnA executable is installed. 79 | /// 80 | const string DEFAULT_QNA_ENVIRONMENTAL_VARIABLE = "QnA"; 81 | 82 | /// 83 | /// Default name of the BigFix QnA executable if one was not provided. 84 | /// 85 | const string DEFAULT_QNA_EXECUTABLE = "qna.exe"; 86 | 87 | /// 88 | /// Default amount of time (in seconds) to wait for the QnA process to return a result 89 | /// before considering it not-responsive. 90 | /// 91 | const int DEFAULT_QNA_EVALUATION_TIMEOUT = 60; 92 | 93 | /// 94 | /// Default amount of time (in milliseconds) the idle monitor will sleep between checking 95 | /// if a timeout event occurred. Values over 1,000 should be avoided as it could cause the 96 | /// idle timeout interval to exceed the 1-second granularity accuracy implied. 97 | /// 98 | const int DEFAULT_QNA_IDLE_POLLING = 300; 99 | 100 | /// 101 | /// Default amount of time (in seconds) the idle monitor will wait before stopping the 102 | /// spawned QnA process due to inactivity. 103 | /// 104 | const int DEFAULT_QNA_IDLE_TIMEOUT = 300; 105 | 106 | private readonly Object _lock = new object(); 107 | 108 | private Process _process; 109 | private DateTime _lastActivity; 110 | private TimeSpan _idleTimeout; 111 | private TimeSpan _evaluationTimeout; 112 | private Task _monitor; 113 | private bool _evaluating; 114 | 115 | /// 116 | /// Amount of time (in seconds) to keep the QnA process running while waiting 117 | /// for new queries. 118 | /// 119 | public int IdleTimeout 120 | { 121 | get { return (int)_idleTimeout.TotalSeconds; } 122 | set 123 | { 124 | lock (_lock) 125 | { 126 | _idleTimeout = TimeSpan.FromSeconds(value); 127 | } 128 | } 129 | } 130 | 131 | /// 132 | /// Amount of time (in seconds) to wait for the QnA process to evaluate a query 133 | /// before considering it not-responsive. 134 | /// 135 | public int EvaluationTimeout 136 | { 137 | get { return (int)_evaluationTimeout.TotalSeconds; } 138 | set 139 | { 140 | lock (_lock) 141 | { 142 | _evaluationTimeout = TimeSpan.FromSeconds(value); 143 | } 144 | } 145 | } 146 | 147 | /// 148 | /// Full path to the BigFix QnA executable. 149 | /// 150 | public string ExecutablePath { get; private set; } 151 | 152 | /// 153 | /// Version of the BigFix QnA executable. 154 | /// 155 | public string Version { get; private set; } 156 | 157 | public Session() : this(null) { } 158 | public Session(string path) 159 | { 160 | EvaluationTimeout = DEFAULT_QNA_EVALUATION_TIMEOUT; 161 | IdleTimeout = DEFAULT_QNA_IDLE_TIMEOUT; 162 | 163 | SetExecutablePath(path); 164 | 165 | if (!SpawnQnaProcess()) 166 | { 167 | throw new Exception("Unable to spawn BigFix QnA process!"); 168 | } 169 | } 170 | 171 | private async Task ProcessIdleMonitor() 172 | { 173 | try 174 | { 175 | while (true) 176 | { 177 | DateTime now = DateTime.Now; 178 | TimeSpan elapsedTime = now - _lastActivity; 179 | 180 | if (_process != null && _evaluating != true && elapsedTime >= _idleTimeout) 181 | { 182 | lock (_lock) 183 | { 184 | try 185 | { 186 | _process.Kill(); 187 | _process.Dispose(); 188 | } 189 | catch (ObjectDisposedException) { } 190 | catch (InvalidOperationException) 191 | { 192 | _process.Dispose(); 193 | _process = null; 194 | } 195 | catch (Win32Exception) 196 | { 197 | _process.Dispose(); 198 | _process = null; 199 | } 200 | finally 201 | { 202 | _process = null; 203 | } 204 | } 205 | } 206 | 207 | await Task.Delay(DEFAULT_QNA_IDLE_POLLING); 208 | } 209 | } 210 | finally 211 | { 212 | lock (_lock) 213 | { 214 | try 215 | { 216 | if (_process != null) 217 | { 218 | if (_process.HasExited == true) 219 | { 220 | _process.Dispose(); 221 | _process = null; 222 | } 223 | if (_process.Responding == false) 224 | { 225 | _process.Kill(); 226 | _process.Dispose(); 227 | _process = null; 228 | } 229 | } 230 | } 231 | catch (ObjectDisposedException) 232 | { 233 | _process = null; 234 | } 235 | catch (InvalidOperationException) 236 | { 237 | _process.Dispose(); 238 | _process = null; 239 | } 240 | catch (Win32Exception) 241 | { 242 | _process.Dispose(); 243 | _process = null; 244 | } 245 | } 246 | } 247 | } 248 | 249 | private bool SpawnQnaProcess() 250 | { 251 | lock (_lock) 252 | { 253 | _lastActivity = DateTime.Now; 254 | 255 | try 256 | { 257 | if (_process != null) 258 | { 259 | if (_process.HasExited == true) 260 | { 261 | _process.Dispose(); 262 | _process = null; 263 | } 264 | if (_process.Responding == false) 265 | { 266 | _process.Kill(); 267 | _process.Dispose(); 268 | _process = null; 269 | } 270 | } 271 | } 272 | catch (ObjectDisposedException) 273 | { 274 | _process = null; 275 | } 276 | catch (InvalidOperationException) 277 | { 278 | _process.Dispose(); 279 | _process = null; 280 | } 281 | catch (Win32Exception) 282 | { 283 | _process.Dispose(); 284 | _process = null; 285 | } 286 | } 287 | 288 | if (_process == null) 289 | { 290 | Process process = null; 291 | try 292 | { 293 | process = new Process(); 294 | process.StartInfo.FileName = this.ExecutablePath; 295 | process.StartInfo.RedirectStandardInput = true; 296 | process.StartInfo.RedirectStandardOutput = true; 297 | process.StartInfo.CreateNoWindow = true; 298 | process.StartInfo.UseShellExecute = false; 299 | process.StartInfo.ErrorDialog = false; 300 | 301 | if (process.Start()) 302 | { 303 | process.StandardInput.AutoFlush = true; 304 | lock (_lock) 305 | { 306 | _process = process; 307 | 308 | if (_monitor == null || _monitor.IsCompleted) 309 | { 310 | _monitor = ProcessIdleMonitor(); 311 | } 312 | } 313 | 314 | return true; 315 | } 316 | else 317 | { 318 | process.Kill(); 319 | process.Dispose(); 320 | } 321 | } 322 | catch 323 | { 324 | return false; 325 | } 326 | 327 | return false; 328 | } 329 | 330 | return _process != null ? _process.Responding == true : false; 331 | } 332 | 333 | private bool SetExecutablePath() 334 | { 335 | List searchPaths = new List(); 336 | 337 | // Environmental variable. 338 | searchPaths.Add(Environment.ExpandEnvironmentVariables(Environment.GetEnvironmentVariable(DEFAULT_QNA_ENVIRONMENTAL_VARIABLE) ?? String.Empty)); 339 | 340 | // Current working directory. 341 | searchPaths.Add(Directory.GetCurrentDirectory()); 342 | 343 | // Look to see if the BigFix Client is installed as the QnA utility is [typically] co-installed along side. 344 | searchPaths.Add(Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\BigFix\EnterpriseClient", "EnterpriseClientFolder", Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\BigFix\EnterpriseClient", "EnterpriseClientFolder", null)) as string); 345 | 346 | // System environmental search path(s). 347 | searchPaths.AddRange(Environment.ExpandEnvironmentVariables(Environment.GetEnvironmentVariable("PATH") ?? String.Empty).Split(new char[] { ';' })); 348 | 349 | foreach (string path in searchPaths) 350 | { 351 | if (!String.IsNullOrWhiteSpace(path)) 352 | { 353 | if (SetExecutablePath(path)) 354 | { 355 | return true; 356 | } 357 | } 358 | } 359 | 360 | return false; 361 | } 362 | 363 | private bool SetExecutablePath(string path) 364 | { 365 | if (String.IsNullOrWhiteSpace(path)) 366 | { 367 | return SetExecutablePath(); 368 | } 369 | 370 | string executablePath = null; 371 | 372 | if (".exe".Equals(Path.GetExtension(path), StringComparison.InvariantCultureIgnoreCase)) 373 | { 374 | executablePath = path; 375 | } 376 | else 377 | { 378 | executablePath = Path.Combine(path, DEFAULT_QNA_EXECUTABLE); 379 | } 380 | 381 | if (File.Exists(executablePath)) 382 | { 383 | try 384 | { 385 | var fileInfo = FileVersionInfo.GetVersionInfo(executablePath); 386 | 387 | if (fileInfo != null && (fileInfo.ProductName.Contains("QnA") || fileInfo.FileDescription.Contains("QnA"))) 388 | { 389 | ExecutablePath = executablePath; 390 | Version = fileInfo.ProductVersion; 391 | 392 | return true; 393 | } 394 | } 395 | catch { } 396 | } 397 | 398 | return false; 399 | } 400 | 401 | public Result Query(string relevance) 402 | { 403 | List answers = new List(); 404 | string error = null; 405 | long evalTime = 0; 406 | 407 | try 408 | { 409 | if (SpawnQnaProcess()) 410 | { 411 | lock (_lock) 412 | { 413 | _evaluating = true; 414 | } 415 | 416 | _process.StandardInput.WriteLine(relevance); 417 | 418 | while (true) 419 | { 420 | string line = _process.StandardOutput.ReadLine(); 421 | 422 | if (line.StartsWith("Q: ")) 423 | { 424 | line = line.Substring(3); 425 | } 426 | 427 | if (String.IsNullOrWhiteSpace(line)) 428 | { 429 | break; 430 | } 431 | 432 | switch (line[0]) 433 | { 434 | case 'A': 435 | answers.Add(line.Substring(3)); 436 | break; 437 | case 'E': 438 | error = line.Substring(3); 439 | break; 440 | case 'T': 441 | if (!long.TryParse(line.Substring(3), out evalTime)) 442 | { 443 | evalTime = 0; 444 | } 445 | break; 446 | } 447 | } 448 | } 449 | else 450 | { 451 | error = "Unable to spawn BigFix QnA process!"; 452 | } 453 | } 454 | catch (Exception e) 455 | { 456 | error = e.Message; 457 | } 458 | finally 459 | { 460 | lock (_lock) 461 | { 462 | _evaluating = false; 463 | _lastActivity = DateTime.Now; 464 | } 465 | } 466 | 467 | return new Result(relevance, answers.ToArray(), error, evalTime); 468 | } 469 | 470 | public void Dispose() 471 | { 472 | if (_process != null) 473 | { 474 | lock (_lock) 475 | { 476 | _process.Kill(); 477 | _process.Dispose(); 478 | } 479 | } 480 | 481 | try 482 | { 483 | if (_monitor != null) 484 | { 485 | if (_monitor.IsCompleted == false) 486 | { 487 | _monitor.Wait(DEFAULT_QNA_IDLE_POLLING); 488 | } 489 | } 490 | } 491 | catch { } 492 | } 493 | } 494 | 495 | } -------------------------------------------------------------------------------- /BigFix/Private/Expand-StructuredRelevanceResult.ps1: -------------------------------------------------------------------------------- 1 | function Expand-StructuredRelevanceResult { 2 | <# 3 | .Synopsis 4 | Expand a Structured Relevance Result. 5 | 6 | .Description 7 | This module internal function is used to expand the Structured Relevance Result objects 8 | returned as a result of calling the Web Reports SOAP API's GetStructuredRelevanceResult 9 | method into a more PowerShell friendly object. 10 | 11 | .Parameter InputObject 12 | The Structured Relevance Result object to expand. 13 | 14 | .Parameter FieldNames 15 | Array of strings representing the names for each resultant tuple field. 16 | 17 | .Parameter Prefix 18 | Prefix to use for auto-generated resultant tuple field names (Default: Field_). 19 | 20 | .Inputs 21 | Any object that follows the GetStructuredRelevanceResult method schema. 22 | 23 | .Outputs 24 | A dynamically-created System.Management.Automation.PSCustomObject object representing 25 | the results of a GetStructuredRelevanceResult method call with all resultant tuple fields 26 | expanded fully. 27 | 28 | .Notes 29 | This function is currently considered for internal module use only and not exported out 30 | for direct use by external entities. As users of this module will not be working directly 31 | with the resultant SOAP API XML, there was no need to make this function public. This will 32 | allow greater flexibility in future optimizations of the processing code paths as no 33 | backwards compatibility has to be provided for. 34 | 35 | .Example 36 | # Expand a Structured Relevance Result object using auto-generated resultant tuple field names 37 | # prefixed with the default 'Field_' (e.g. 'Field_0', 'Field_1', ...). 38 | Expand-StructuredRelevanceResult -InputObject $StructuredResult 39 | 40 | .Example 41 | # Expand a Structured Relevance Result object using the tuple field names 'Id', 'Name', and 'Value'. 42 | Expand-StructuredRelevanceResult -InputObject $StructuredResult -FieldNames Id, Name, Value 43 | 44 | .Example 45 | # Expand a Structured Relevance Result object using auto-generated resultant tuple field names 46 | # prefixed with 'F_' (e.g. 'F_0', 'F_1', ...). 47 | Expand-StructuredRelevanceResult -InputObject $StructuredResult 48 | 49 | #> 50 | [CmdletBinding()] 51 | [OutputType([System.Array])] 52 | [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', 'Prefix', Justification = 'This is a false positive. Rule does not validate string interpolation usage.')] 53 | Param( 54 | [Parameter( 55 | Mandatory = $true, 56 | Position = 0, 57 | ValueFromPipeline = $true, 58 | HelpMessage = 'The Structured Relevance Result object to expand.' 59 | )] 60 | [object]$InputObject, 61 | 62 | [Parameter( 63 | Mandatory = $false, 64 | ValueFromPipelineByPropertyName = $true, 65 | HelpMessage = 'Array of strings representing the names for each resultant tuple field.' 66 | )] 67 | [string[]]$FieldNames = $null, 68 | 69 | [Parameter( 70 | Mandatory = $false, 71 | HelpMessage = 'Prefix to use for auto-generated resultant tuple field names (Default: Field_).' 72 | )] 73 | [string]$Prefix = 'Field_' 74 | ) 75 | 76 | Begin { 77 | $ExtractValue = [ScriptBlock] { 78 | param($Item) 79 | if ($Item.Items) { 80 | & $ExtractValue $Item.Items 81 | } 82 | else { 83 | $Item 84 | } 85 | } 86 | } 87 | 88 | Process { 89 | foreach ($Item in $InputObject) { 90 | if ($Item.results) { 91 | $Hash = [ordered]@{} 92 | foreach ($Result in $Item.results.Items) { 93 | if ($Result.Items) { 94 | $ExpandedItems = & $ExtractValue $Result.Items 95 | } 96 | else { 97 | $ExpandedItems = $Result 98 | } 99 | 100 | if ($null -eq $FieldNames) { 101 | @(, $ExpandedItems) 102 | } 103 | else { 104 | $FieldsCount = $FieldNames.Count 105 | if ($FieldsCount -lt $ExpandedItems.Count) { 106 | $FieldNames += (0 .. ($ExpandedItems.Count - $FieldsCount)) | ForEach-Object { "$($Prefix)$($FieldCount + $_)" } 107 | } 108 | 109 | $Index = 0 110 | foreach ($ExpandedItem in $ExpandedItems) { 111 | $Hash[$FieldNames[$Index++]] = $ExpandedItem 112 | } 113 | [PSCustomObject]$Hash 114 | } 115 | } 116 | } 117 | elseif ($Item.Items) { 118 | Expand-StructuredRelevanceResult -InputObject @{ InputObject = $Item } 119 | } 120 | } 121 | } 122 | } -------------------------------------------------------------------------------- /BigFix/Private/Test-Uri.ps1: -------------------------------------------------------------------------------- 1 | function Test-Uri { 2 | [CmdletBinding()] 3 | [OutputType([boolean])] 4 | [OutputType([string], [System.Uri], ParameterSetName = 'PASSTHRU')] 5 | Param( 6 | [Parameter( 7 | Mandatory = $true, 8 | Position = 0, 9 | ValueFromPipeline = $true, 10 | HelpMessage = 'URI to validate' 11 | )] 12 | [string]$Uri, 13 | 14 | [Parameter( 15 | Mandatory = $false, 16 | HelpMessage = 'Kind of URI that is expected' 17 | )] 18 | [ValidateSet('Absolute', 'Relative', 'RelativeOrAbsolute')] 19 | [string]$Kind = 'Absolute', 20 | 21 | [Parameter( 22 | Mandatory = $false, 23 | HelpMessage = 'Scheme(s) that must be used' 24 | )] 25 | [ValidateNotNullOrEmpty()] 26 | [string[]]$Scheme = $null, 27 | 28 | [Parameter( 29 | Mandatory = $false 30 | )] 31 | [Switch]$PassThru = $false, 32 | 33 | [Parameter( 34 | Mandatory = $false, 35 | HelpMessage = 'Transform output into a System.Uri object' 36 | )] 37 | [ValidateNotNullOrEmpty()] 38 | [Switch]$Transform = $false, 39 | 40 | [Parameter( 41 | Mandatory = $false, 42 | HelpMessage = 'Throw instead of just returning $false' 43 | )] 44 | [Switch]$Throw = $false 45 | ) 46 | 47 | Begin { 48 | [System.UriKind]$UriKind = switch($Kind) { 49 | 'Absolute' { [System.UriKind]::Absolute; break; } 50 | 'Relative' { [System.UriKind]::Relative; break; } 51 | 'RelativeOrAbsolute' { [System.UriKind]::RelativeOrAbsolute; break; } 52 | default { [System.UriKind]::Absolute; break; } 53 | } 54 | 55 | Write-Verbose -Message "Test-Uri will be validating using UriKind '$($UriKind)'" 56 | } 57 | 58 | Process { 59 | Write-Debug -Message "Testing '$($Uri)' is a well-formed URI of kind $($UriKind)" 60 | if ([System.Uri]::IsWellFormedUriString($Uri, $UriKind) -eq $false) { 61 | $Message = "Uri '$($Uri)' is NOT well-formed" 62 | 63 | if ($Throw) { 64 | throw $Message 65 | } 66 | 67 | Write-Verbose -Message $Message 68 | if (!$PassThru) { 69 | $false 70 | } 71 | return 72 | } 73 | 74 | Write-Debug -Message "Testing '$($Uri)' is instantiatable" 75 | [System.Uri]$ParsedUri = $null 76 | if ([System.Uri]::TryCreate($Uri, $UriKind, [ref] $ParsedUri) -eq $false) { 77 | $Message = "Uri '$($Uri)' is NOT instantiatable" 78 | 79 | if ($Throw) { 80 | throw $Message 81 | } 82 | 83 | Write-Verbose -Message $Message 84 | if (!$PassThru) { 85 | $false 86 | } 87 | return 88 | } 89 | 90 | if ($null -ne $Scheme) { 91 | Write-Debug -Message "Testing '$($Uri)' is using an acceptable scheme" 92 | 93 | [boolean]$Matched = $false 94 | Foreach($Match in @($Scheme)) { 95 | if ($Match -eq $ParsedUri.Scheme) { 96 | Write-Debug -Message "Uri '$($Uri)' is using the scheme '$($Match)'" 97 | 98 | $Matched = $true 99 | break 100 | } else { 101 | Write-Debug -Message "Uri '$($Uri)' is NOT using the scheme '$($Match)'" 102 | } 103 | } 104 | 105 | if ($Matched -eq $false) { 106 | $Message = "Uri '$($Uri)' is NOT using an acceptable scheme" 107 | 108 | if ($Throw) { 109 | throw $Message 110 | } 111 | 112 | Write-Verbose -Message $Message 113 | if (!$PassThru) { 114 | $false 115 | } 116 | return 117 | } 118 | } 119 | 120 | if ($PassThru) { 121 | if ($Transform) { 122 | $ParsedUri 123 | } else { 124 | $Uri 125 | } 126 | } else { 127 | $true 128 | } 129 | return 130 | } 131 | } -------------------------------------------------------------------------------- /BigFix/Public/Get-QnaSession.ps1: -------------------------------------------------------------------------------- 1 | function Get-QnaSession { 2 | <# 3 | .Synopsis 4 | Gets the previously instantiated Qna Session object. 5 | 6 | .Description 7 | The Get-QnaSession function is used to obtain the Qna Session object last instantiated 8 | by a call to New-QnaSession in the current scope. If called with the -Throw switch, the 9 | call will throw a fault in the event that no previously instantiated Qna Session object 10 | is found. 11 | 12 | .Parameter Throw 13 | Switch specifying that the call should throw a fault in the event that no previously 14 | instantiated Qna Session object is found. 15 | 16 | .Inputs 17 | None. This function does not accept pipeline input. 18 | 19 | .Outputs 20 | The last BigFix.Qna.Session object instantiated via a call to New-QnaSession, or nothing 21 | if no instantiated object exists. 22 | 23 | .Example 24 | # Gets the last instantiated Qna Session object. 25 | Get-QnaSession 26 | 27 | .Example 28 | # Gets the last instantiated Qna Session object or throw a fault. 29 | Get-QnaSession -Throw 30 | 31 | #> 32 | [CmdletBinding()] 33 | [OutputType('BigFix.Qna.Session')] 34 | Param ( 35 | [Parameter( 36 | Mandatory = $false, 37 | HelpMessage = 'Throw an error if no previously created Qna Session was found.' 38 | )] 39 | [Switch]$Throw = $false 40 | ) 41 | 42 | $Session = Get-Variable -Name QnaSession -ValueOnly -Scope Script -ErrorAction SilentlyContinue 43 | 44 | if ($null -ne $Session) { 45 | return $Session 46 | } 47 | 48 | if ($true -eq $Throw) { 49 | throw 'No previously created Qna Session was found! Please call New-QnaSession first to create a new session instance.' 50 | } 51 | 52 | return 53 | } -------------------------------------------------------------------------------- /BigFix/Public/Get-WebReportsServer.ps1: -------------------------------------------------------------------------------- 1 | function Get-WebReportsServer { 2 | <# 3 | .Synopsis 4 | Gets registered Web Reports Server objects. 5 | 6 | .Description 7 | Gets registered Web Reports Server objects. When called without parameters, a listing of 8 | all registered Web Reports Server objects will be returned. If a URI is provided, attempt 9 | to return the matching Web Reports Server object. If called with the -Default switch, the 10 | registered default Web Reports Server object will be returned (if found). 11 | 12 | .Parameter Uri 13 | Specifies the well-formed absolute URI of the registered Web Reports Server object to return. 14 | 15 | .Parameter Default 16 | Switch specifying that the default registered Web Reports Server object is to be returned. 17 | 18 | .Inputs 19 | A System.String specifying the well-formed absolute URI of the registered Web Reports Server object 20 | to return. 21 | 22 | .Outputs 23 | A BigFix.WebReports.Server object representing a specific Web Reports Server. 24 | 25 | .Example 26 | # Gets a listing of all registered Web Reports Server objects. 27 | Get-WebReportsServer 28 | 29 | .Example 30 | # Gets the registered Web Reports Server object matching the Web Reports Server URI 31 | # 'https://webreports/' 32 | Get-WebReportsServer -Uri 'https://webreports/' 33 | 34 | .Example 35 | # Gets the default registered Web Reports Server object. 36 | Get-WebReportsServer -Default 37 | 38 | #> 39 | [CmdletBinding()] 40 | [OutputType('BigFix.WebReports.Server')] 41 | Param( 42 | [Parameter( 43 | Mandatory = $false, 44 | Position = 0, 45 | HelpMessage = 'Well-formed absolute URI to the Web Reports Server (e.g. https://webreports/)' 46 | )] 47 | [ValidateScript( { Test-Uri -Uri $_ -Kind Absolute -Throw })] 48 | [string] $Uri = $null, 49 | 50 | [Parameter( 51 | Mandatory = $false, 52 | HelpMessage = 'Get the default Web Reports Server (if set)' 53 | )] 54 | [Switch] $Default = $false 55 | ) 56 | 57 | if ($Default -eq $true) { 58 | return Get-Variable -Name WebReportsServersDefault -ValueOnly -Scope Script -ErrorAction SilentlyContinue 59 | } 60 | 61 | $Servers = Get-Variable -Name WebReportsServers -ValueOnly -Scope Script -ErrorAction SilentlyContinue 62 | 63 | if ($null -eq $Uri -or $Uri -eq "") { 64 | return [BigFix.WebReports.Server[]]@($Servers) 65 | } 66 | 67 | foreach ($server in @($Servers)) { 68 | if ($server.Uri -eq $Uri) { 69 | return $server 70 | } 71 | } 72 | 73 | return 74 | } -------------------------------------------------------------------------------- /BigFix/Public/Get-WebReportsSession.ps1: -------------------------------------------------------------------------------- 1 | function Get-WebReportsSession { 2 | <# 3 | .Synopsis 4 | Gets the current Web Reports Session. 5 | 6 | .Description 7 | Gets the current Web Reports Session created during the last call to New-WebReportsSession. 8 | 9 | .Example 10 | # Get the current Web Reports Session. 11 | Get-WebReportsSession 12 | 13 | #> 14 | [CmdletBinding()] 15 | [OutputType('BigFix.WebReports.Session')] 16 | Param() 17 | 18 | $Session = Get-Variable -Name WebReportsSession -ValueOnly -Scope Script -ErrorAction SilentlyContinue 19 | 20 | if ($null -eq $Session) { 21 | throw 'No previously created Web Reports Session was found. Use New-WebReportsSession to create a new instance.' 22 | } 23 | 24 | return $Session 25 | } -------------------------------------------------------------------------------- /BigFix/Public/Invoke-EvaluateClientRelevance.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-EvaluateClientRelevance { 2 | <# 3 | .Synopsis 4 | Evaluates Client Relevance statements. 5 | 6 | .Description 7 | Evaluates Client Relevance statements in the established Qna Session, 8 | parsing results into a more PowerShell-friendly format. Relevance Statements can 9 | be provided via the -Relevance parameter or the pipeline. Results are returned 10 | sequentially to the pipeline as they are evaluated in the Qna Session. 11 | 12 | .Parameter Relevance 13 | Specifies the Client Relevance statement(s) to evaluate in the Qna Session. 14 | 15 | .Parameter Session 16 | Specifies the Qna Session to evaluate the relevance in. If not provided, 17 | will attempt to use the last Qna Session created via New-QnaSession, creating 18 | a new Qna Session in the event none exists. 19 | 20 | .Inputs 21 | One or more strings representing complete valid Client Relevance expressions to 22 | evaluate. 23 | 24 | .Outputs 25 | A BigFix.Qna.Result object for each Client Relevance expression evaluated. 26 | 27 | .Example 28 | # Evaluate the Client Relevance statement 'computer name'. 29 | Invoke-EvaluateClientRelevance -Relevance 'computer name' 30 | 31 | .Example 32 | # Evaluate the Client Relevance statements 'now' and 'version of client' using 33 | # the pipeline for input. 34 | 'now','version of client' | Invoke-EvaluateClientRelevance 35 | 36 | .Example 37 | # Evaluate the Client Relevance statement 'computer name' using a specific Qna Session. 38 | Invoke-EvaluateClientRelevance -Relevance 'computer name' -Session $QnaSession 39 | 40 | #> 41 | [CmdletBinding()] 42 | [OutputType('BigFix.Qna.Result')] 43 | Param ( 44 | [Parameter( 45 | Position = 0, 46 | Mandatory = $true, 47 | ValueFromPipeline = $true, 48 | ValueFromPipelineByPropertyName = $true, 49 | HelpMessage = 'Client Relevance statement to evaluate' 50 | )] 51 | [string[]]$Relevance, 52 | 53 | [Parameter( 54 | Mandatory = $false, 55 | ValueFromPipelineByPropertyName = $true, 56 | HelpMessage = 'Qna Session to perform the evaluation within' 57 | )] 58 | [BigFix.Qna.Session]$Session = $null 59 | ) 60 | 61 | Begin { 62 | if ($null -eq $Session) { 63 | Write-Debug -Message 'Obtaining the current Qna Session via Get-QnaSession' 64 | $Session = Get-QnaSession 65 | } 66 | 67 | if ($null -eq $Session) { 68 | Write-Debug -Message 'Creating a new Qna Session via New-QnaSession' 69 | $Session = New-QnaSession 70 | } 71 | 72 | Write-Verbose -Message "Using Qna $($Session.ExecutablePath) (Version: $($Session.Version))" 73 | } 74 | 75 | Process { 76 | foreach ($question in $Relevance) { 77 | Write-Verbose -Message "Evaluating Client Relevance: $($question)" 78 | $Session.Query($question) 79 | } 80 | } 81 | } -------------------------------------------------------------------------------- /BigFix/Public/Invoke-EvaluateSessionRelevance.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-EvaluateSessionRelevance { 2 | <# 3 | .Synopsis 4 | Evaluates Session Relevance statements. 5 | 6 | .Description 7 | Evaluates Session Relevance statements on the established Web Reports Session, 8 | parsing results into a more PowerShell-friendly format. Relevance Statements can 9 | be provided via the -Relevance parameter or the pipeline. Results are returned 10 | only after all Relevance Statements have completed. 11 | 12 | .Parameter Relevance 13 | Specifies the Session Relevance statement to evaluate on the Web Reports Session. 14 | 15 | .Parameter Session 16 | Specifies the Web Reports Session to evaluate the relevance on. If not provided, 17 | will attempt to use the last Web Reports Session created via New-WebReportsSession. 18 | 19 | .Parameter FieldNames 20 | Specifies a listing of field names to translate the evaluation tuple results into. 21 | 22 | .Example 23 | # Evaluate the Session Relevance statement 'number of bes computers'. 24 | Invoke-EvaluateSessionRelevance -Relevance 'number of bes computers' 25 | 26 | .Example 27 | # Evaluate the Session Relevance statement '(id of it, (if (exists name of it) then (name of it) 28 | # else ("")) of it) of bes computers', parsing results into objects with the field 29 | # names 'Id' and 'Name'. 30 | Invoke-EvaluateSessionRelevance -Relevance '(id of it, (if (exists name of it) then (name of it) else ("")) of it) of bes computers' -FieldNames @('Id', 'Name') 31 | 32 | #> 33 | [CmdLetBinding()] 34 | [OutputType('BigFix.SessionRelevanceResult')] 35 | Param( 36 | [Parameter( 37 | Mandatory = $true, 38 | Position = 0, 39 | ValueFromPipeline = $true, 40 | HelpMessage = 'Session Relevance statement to evaluate' 41 | )] 42 | [ValidateNotNullOrEmpty()] 43 | [string]$Relevance, 44 | 45 | [Parameter( 46 | Mandatory = $false, 47 | HelpMessage = 'Web Reports Session to perform the evaluation in' 48 | )] 49 | [ValidateNotNull()] 50 | [PSTypeName('BigFix.WebReports.Session')]$Session = (Get-WebReportsSession), 51 | 52 | [Parameter( 53 | Mandatory = $false, 54 | HelpMessage = 'Array of strings representing the names for each resultant tuple field' 55 | )] 56 | [string[]]$FieldNames = $null 57 | ) 58 | 59 | Begin { 60 | if ($null -eq $Session) { 61 | throw "Cannot validate argument on parameter 'Session'. The argument is null. Call New-WebReportsSession first or provide a valid value for the argument, and then try running the command again." 62 | } 63 | 64 | if ($Session.State -ne 'Connected' -and $Session.State -ne 'Connecting') { 65 | $Session.Connect() 66 | } 67 | 68 | if ($Session.State -eq 'Connecting' -or $null -eq $Session.SessionToken) { 69 | $header = New-Object "$($Session.Service.GetType().Namespace).LoginHeader" 70 | $header.username = $Session.Credential.UserName 71 | $header.password = $Session.Credential.GetNetworkCredential().Password 72 | } 73 | else { 74 | $header = New-Object "$($Session.Service.GetType().Namespace).AuthenticateHeader" 75 | $header.username = $Session.Credential.UserName 76 | $header.sessionToken = $Session.SessionToken 77 | } 78 | 79 | $Session.Service.RequestHeaderElement = $header 80 | } 81 | 82 | Process { 83 | $result = [PSCustomObject]@{ 84 | PSTypeName = 'BigFix.SessionRelevanceResult' 85 | Relevance = $Relevance 86 | Results = $null 87 | Error = $null 88 | Time = $null 89 | EvaluationTime = $null 90 | } 91 | 92 | $timer = [System.Diagnostics.Stopwatch]::StartNew() 93 | try { 94 | Write-Verbose -Message "Evaluating Relevance: $Relevance" 95 | 96 | $structuredResult = $Session.Service.GetStructuredRelevanceResult($Relevance) 97 | 98 | $result.EvaluationTime = $structuredResult.evaltime 99 | 100 | if ($structuredResult.error) { 101 | $result.Error = $structuredResult.error 102 | } 103 | else { 104 | $result.Results = Expand-StructuredRelevanceResult -InputObject $structuredResult -FieldNames $FieldNames 105 | } 106 | } 107 | catch { 108 | $result.Error = $PSItem.ToString() 109 | $Session.State = 'Error' 110 | } 111 | finally { 112 | $null = $timer.Stop() 113 | $result.Time = $timer.Elapsed 114 | 115 | if ($result.Error) { 116 | Write-Verbose -Message "Evaluation failed: $($result.Error)" 117 | } 118 | else { 119 | $Session.SessionToken = $Session.Service.ResponseHeaderElement.sessionToken 120 | Write-Verbose -Message "Evaluation produced $($result.Results.Count.ToString('N0')) answer(s) in $($result.Time)." 121 | } 122 | } 123 | 124 | return $result 125 | } 126 | } -------------------------------------------------------------------------------- /BigFix/Public/New-QnaSession.ps1: -------------------------------------------------------------------------------- 1 | function New-QnaSession { 2 | <# 3 | .Synopsis 4 | Instantiate a new Qna Session object. 5 | 6 | .Description 7 | Creates a new Qna Session object and expose it into the current scope. By default, it 8 | will attempt to link to the qna.exe utility application binary using the following 9 | search path order: 10 | 1. Directory defined within the environmental variable 'QnA'. 11 | 2. Current working directory. 12 | 3. Directory where the BigFix Client is registered. 13 | 4. Every directory defined within the environmental variable 'PATH', in the order it 14 | is defined. 15 | 16 | If called with the -ExecutablePath parameter and provided with the full path of the 17 | qna.exe utility, the session will attempt to link to that binary. 18 | 19 | .Parameter ExecutablePath 20 | Path to the BigFix Qna utility executable (i.e. qna.exe) 21 | 22 | .Inputs 23 | None. This function does not accept pipeline input. 24 | 25 | .Outputs 26 | An instantiated BigFix.Qna.Session object. 27 | 28 | .Example 29 | # Create a new Qna Session using the qna.exe utility application installed as part 30 | # of the BigFix Client installation. 31 | New-QnaSession 32 | 33 | .Example 34 | # Create a new Qna Session using the qna.exe utility application at the provided path. 35 | New-QnaSession -ExecutablePath 'C:\Tools\BigFix\qna.exe' 36 | 37 | #> 38 | [CmdletBinding()] 39 | [OutputType('BigFix.Qna.Session')] 40 | Param ( 41 | [Parameter( 42 | Mandatory = $false, 43 | HelpMessage = 'Path to the BigFix Qna utility executable (i.e. qna.exe)' 44 | )] 45 | [string]$ExecutablePath = $null 46 | ) 47 | 48 | try { 49 | $Session = $null 50 | 51 | if ([String]::IsNullOrWhiteSpace($ExecutablePath)) { 52 | $Session = Get-Variable -Name QnaSession -ValueOnly -Scope Script -ErrorAction SilentlyContinue 53 | } 54 | 55 | if ($null -eq $Session) { 56 | $Session = New-Object -Type BigFix.Qna.Session -ArgumentList $ExecutablePath 57 | $null = Set-Variable -Name QnaSession -Value $Session -Scope Script -Force -ErrorAction SilentlyContinue 58 | } 59 | 60 | $Session 61 | } catch { 62 | throw "Unable to establish a Qna Session! Please check that the BigFix Qna utility executable (i.e. qna.exe) is in the BigFix Client directory, in the system path, or present at the provided path. $_" 63 | } 64 | } -------------------------------------------------------------------------------- /BigFix/Public/New-WebReportsServer.ps1: -------------------------------------------------------------------------------- 1 | function New-WebReportsServer { 2 | <# 3 | .Synopsis 4 | Creates a new Web Reports Server object. 5 | 6 | .Description 7 | Creates a new Web Reports Server object to use when calling New-WebReportsSession, 8 | and [optionally] both registers and sets it as the default Web Reports Server object. 9 | 10 | .Parameter Uri 11 | Specifies a well-formed absolute URI to the Web Reports Server. 12 | 13 | .Parameter Fqdn 14 | Specifies the Fully Qualified Domain Name (FQDN) of the Web Reports Server. This 15 | can be entered either as just the hostname, IP address, or the FQDN (preferred). 16 | 17 | .Parameter Port 18 | Specifies the TCP port number of the Web Reports Server, if a non-standard (80/443) 19 | port is being used. 20 | 21 | .Parameter Ssl 22 | Switch specifying if SSL (HTTPS) is to be used when connecting to the Web Reports Server. 23 | 24 | .Parameter NoPersist 25 | Switch specifying that the Web Reports Server object created not be persisted to the 26 | registry nor set as the default. 27 | 28 | .Example 29 | # Create a new Web Reports Server object to the server 'webreports' over HTTPS, 30 | # using URI nomenclature. 31 | New-WebReportsServer -Uri 'https://webreports/' 32 | 33 | .Example 34 | # Create a new Web Reports Server object to the server 'webreports' over HTTPS, 35 | # using URI nomenclature, and requesting it be non-persisted. 36 | New-WebReportsServer -Uri 'https://webreports/' -NoPersist 37 | 38 | .Example 39 | # Create a new Web Reports Server object to the server 'webreports' over HTTP on 40 | # the default HTTP port (80). 41 | New-WebReportsServer -Fqdn 'webreports' 42 | 43 | .Example 44 | # Create a new Web Reports Server object to the server 'webreports' over HTTP on 45 | # the non-standard TCP port (8080). 46 | New-WebReportsServer -Fqdn 'webreports' -Port 8080 47 | 48 | .Example 49 | # Create a new Web Reports Server object to the server 'webreports' over HTTP on 50 | # the non-standard TCP port (8080) and request it to be non-persisted. 51 | New-WebReportsServer -Fqdn 'webreports' -Port 8080 -NoPersist 52 | 53 | .Example 54 | # Create a new Web Reports Server object to the server 'webreports' over HTTPS on 55 | # the default HTTPS port (443). 56 | New-WebReportsServer -Fqdn 'webreports' -Ssl 57 | 58 | .Example 59 | # Create a new Web Reports Server object to the server 'webreports' over HTTPS on 60 | # the non-standard TCP port (8443). 61 | New-WebReportsServer -Fqdn 'webreports' -Port 8443 -Ssl 62 | 63 | .Example 64 | # Create a new Web Reports Server object to the server 'webreports' over HTTPS on 65 | # the non-standard TCP port (8443) and request it to be non-persisted. 66 | New-WebReportsServer -Fqdn 'webreports' -Port 8443 -Ssl -NoPersist 67 | 68 | #> 69 | [CmdLetBinding(DefaultParameterSetName = 'URI')] 70 | [OutputType('BigFix.WebReports.Server')] 71 | Param( 72 | [Parameter( 73 | Mandatory = $true, 74 | Position = 0, 75 | ParameterSetName = 'URI', 76 | HelpMessage = 'Well-formed absolute URI to the Web Reports Server (e.g. https://webreports/)' 77 | )] 78 | [ValidateScript( { Test-Uri -Uri $_ -Kind Absolute -Throw })] 79 | [string]$Uri, 80 | 81 | [Parameter( 82 | Mandatory = $true, 83 | Position = 0, 84 | ParameterSetName = 'FQDN', 85 | HelpMessage = 'FQDN of the Web Reports Server (e.g. webreports)' 86 | )] 87 | [ValidateNotNullOrEmpty()] 88 | [string]$Fqdn, 89 | 90 | [Parameter( 91 | Mandatory = $false, 92 | Position = 1, 93 | ParameterSetName = 'FQDN', 94 | HelpMessage = 'TCP port of the Web Reports Server (commonly port 80 for HTTP, 443 for HTTPS)' 95 | )] 96 | [int]$Port = -1, 97 | 98 | [Parameter( 99 | Mandatory = $false, 100 | ParameterSetName = 'FQDN', 101 | HelpMessage = 'Use HTTPS (SSL) when communicating with the Web Reports Server' 102 | )] 103 | [Switch]$Ssl = $false, 104 | 105 | [Parameter( 106 | Mandatory = $false, 107 | HelpMessage = 'Do not persist the resulting Web Reports Server object' 108 | )] 109 | [Switch]$NoPersist = $false 110 | ) 111 | 112 | if ($PSCmdlet.ParameterSetName -eq 'URI') { 113 | [System.Uri]$ParsedUri = Test-Uri -Uri $Uri -Kind Absolute -Scheme @([System.Uri]::UriSchemeHttp, [System.Uri]::UriSchemeHttps) -PassThru -Transform 114 | 115 | if ($null -eq $ParsedUri) { 116 | throw "Cannot validate argument on parameter 'Uri'. The argument ""$($Uri)"" is not a well-formed absolute HTTP or HTTPS URI. Supply an argument that is a well-formed absolute HTTP or HTTPS URI and try the command again." 117 | } 118 | 119 | $Fqdn = $ParsedUri.Host 120 | $Port = if ($ParsedUri.IsDefaultPort) { -1 } else { $ParsedUri.Port } 121 | $Ssl = $ParsedUri.Scheme -eq [System.Uri]::UriSchemeHttps 122 | } 123 | else { 124 | if (![System.Uri]::CheckHostName($Fqdn)) { 125 | throw "Cannot validate argument on parameter 'Fqdn'. The argument ""$($Fqdn)"" is not a valid FQDN. Supply an argument that is a FQDN and try the command again." 126 | } 127 | } 128 | 129 | $scheme = if ($Ssl) { [System.Uri]::UriSchemeHttps } else { [System.Uri]::UriSchemeHttp } 130 | [System.UriBuilder]$uriBuilder = New-Object -TypeName System.UriBuilder -ArgumentList $scheme, $Fqdn, $Port 131 | $Uri = $uriBuilder.ToString() 132 | 133 | $uriBuilder.Query = 'wsdl' 134 | 135 | $server = [PSCustomObject]@{ 136 | PSTypeName = 'BigFix.WebReports.Server' 137 | Uri = $Uri 138 | Wsdl = $uriBuilder.ToString() 139 | } 140 | $server = $server | Add-Member -MemberType ScriptMethod -Name ToString -Value { $this.Uri } -Force -PassThru 141 | 142 | if ($true -ne $NoPersist) { 143 | $null = Set-WebReportsServer -Server $server 144 | } 145 | 146 | return $server 147 | } 148 | -------------------------------------------------------------------------------- /BigFix/Public/New-WebReportsSession.ps1: -------------------------------------------------------------------------------- 1 | function New-WebReportsSession { 2 | <# 3 | .Synopsis 4 | Create a Web Reports Session object. 5 | 6 | .Description 7 | Creates a new Web Reports Session object exposing the BigFix Web Reports SOAP API. 8 | This session object is used by the other cmdlets in this module. 9 | 10 | .Parameter Default 11 | Use the default Web Reports Server previously defined to establish the session 12 | with. The default Web Reports Server is the last one created using 13 | New-WebReportsServer or Set-WebReportsServer. Get-WebReportsServer -Default will 14 | return the current default. 15 | 16 | .Parameter Server 17 | Specifies the Web Reports Server object (created using New-WebReportsServer 18 | or returned from Get-WebReportsServer) to establish the session with. 19 | 20 | .Parameter Uri 21 | Specifies a well-formed absolute URI to the Web Reports Server to establish 22 | the session with. A new Web Reports Server object will be registered 23 | if one is not already found matching the URI. 24 | 25 | .Parameter Credential 26 | Specifies the Web Reports account either as "myuser", "domain\myuser", or a 27 | PSCredential object. Omitting or providing a $null or 28 | [System.Management.Automation.PSCredential]::Empty will prompt the caller. 29 | 30 | .Example 31 | # Create a Web Reports Session object to the default Web Reports Server, 32 | # prompting for credentials. 33 | New-WebReportsSession -Default 34 | 35 | .Example 36 | # Create a Web Reports Session object to the Web Reports Server defined in 37 | # the $MyServer variable, prompting for credentials. 38 | New-WebReportsSession -Server $MyServer 39 | 40 | .Example 41 | # Create a Web Reports Session object to the server 'webreports' over HTTPS, 42 | # prompting for credentials. 43 | New-WebReportsSession -Uri 'https://webreports/' 44 | 45 | .Example 46 | # Create a Web Reports Session object to the server 'webreports' over HTTP, 47 | # prompting for credentials. 48 | New-WebReportsSession -Uri 'http://webreports/' 49 | 50 | .Example 51 | # Create a Web Reports Session object to the server 'webreports' over HTTP 52 | # on port 8080, prompting for credentials. 53 | New-WebReportsSession -Uri 'http://webreports:8080/' 54 | 55 | .Example 56 | # Create a Web Reports Session object to the server 'webreports' over HTTPS, 57 | # using the [PSCredential] credential object in the variable $credential. 58 | New-WebReportsSession -Uri 'https://webreports/' -Credential $credential 59 | 60 | #> 61 | [CmdletBinding(DefaultParameterSetName = 'URI')] 62 | [OutputType('BigFix.WebReports.Session')] 63 | [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', 'Default', Justification = 'This is a false positive. Rule does not validate $PSCmdlet.ParameterSetName switch usage checks.')] 64 | Param ( 65 | [Parameter( 66 | Mandatory = $true, 67 | ParameterSetName = 'DEFAULT', 68 | HelpMessage = 'Use the default Web Reports Server (see Set-WebReportsServer)' 69 | )] 70 | [Switch]$Default, 71 | 72 | [Parameter( 73 | Mandatory = $true, 74 | Position = 0, 75 | ParameterSetName = 'SERVER', 76 | HelpMessage = 'Web Reports Server object for the Web Reports Server' 77 | )] 78 | [ValidateNotNull()] 79 | [PSTypeName('BigFix.WebReports.Server')]$Server, 80 | 81 | [Parameter( 82 | Mandatory = $true, 83 | Position = 0, 84 | ParameterSetName = 'URI', 85 | HelpMessage = 'Well-formed absolute URI to the Web Reports Server (e.g. https://webreports/)' 86 | )] 87 | [ValidateScript( { Test-Uri -Uri $_ -Kind Absolute -Throw })] 88 | [String]$Uri, 89 | 90 | [Parameter ( 91 | Mandatory = $false, 92 | HelpMessage = 'Web Reports account, entered as "myuser", "domain\myuser", or a PSCredential object' 93 | )] 94 | [ValidateNotNull()] 95 | [System.Management.Automation.Credential()] 96 | [System.Management.Automation.PSCredential]$Credential = [System.Management.Automation.PSCredential]::Empty 97 | ) 98 | 99 | if ('DEFAULT' -eq $PSCmdlet.ParameterSetName) { 100 | $Server = Get-WebReportsServer -Default 101 | 102 | if ($null -eq $Server) { 103 | throw 'There is no default Web Reports Server defined!' 104 | } 105 | } 106 | 107 | $session = [PSCustomObject]@{ 108 | PSTypeName = 'BigFix.WebReports.Session' 109 | Server = if ('DEFAULT' -eq $PSCmdlet.ParameterSetName) { $Server } elseif ('SERVER' -eq $PSCmdlet.ParameterSetName) { $Server } else { New-WebReportsServer -Uri $Uri } 110 | State = 'Unknown' 111 | Credential = $Credential 112 | Service = $null 113 | SessionToken = $null 114 | MaximumParseDepth = 6 115 | } 116 | 117 | $connect = { 118 | if ('Connected' -eq $this.State) { 119 | Write-Verbose -Message "Already connected to Web Reports Server: $($this.Server)" 120 | return $true 121 | } 122 | 123 | if ($null -eq $this.Credential -or [System.Management.Automation.PSCredential]::Empty -eq $this.Credential) { 124 | Write-Verbose -Message 'Prompting for account credentials.' 125 | $credential = Get-Credential -Message "Please enter credentials for Web Reports Server '$($this.Server)'" 126 | 127 | if ($null -eq $credential) { 128 | Write-Verbose -Message 'Account credentials were not provided!' 129 | 130 | $this.State = 'Error' 131 | 132 | return $false 133 | } 134 | 135 | $this.Credential = $credential 136 | $this.State = 'Unknown' 137 | } 138 | 139 | if ($null -eq $this.Service) { 140 | Write-Verbose -Message "Obtaining Web Reports API service descriptor '$($this.Server.Wsdl)'." 141 | try { 142 | $this.Service = New-WebServiceProxy -Uri $this.Server.Wsdl 143 | 144 | if ($null -eq $this.Service) { 145 | Write-Verbose -Message "Unable to obtain and/or instantiate the Web Reports API service descriptor '$($this.Server.Wsdl)'!" 146 | 147 | $this.State = 'Error' 148 | 149 | return $false 150 | } 151 | } 152 | catch { 153 | Write-Verbose -Message "Unable to obtain and/or instantiate the Web Reports API service descriptor '$($this.Server.Wsdl)'!" 154 | Write-Verbose -Message $PSItem 155 | 156 | $this.State = 'Error' 157 | 158 | return $false 159 | } 160 | } 161 | 162 | Write-Verbose -Message "Connecting to Web Reports Server: $($this.Server)" 163 | try { 164 | $this.State = 'Connecting' 165 | 166 | $version = $this.Evaluate('maximum of versions of modules') 167 | 168 | if ($version.Error) { 169 | Write-Verbose -Message "Connection to Web Reports Server '$($this.Server)' failed!" 170 | Write-Verbose -Message $version.Error 171 | 172 | $this.State = 'Error' 173 | 174 | return $false 175 | } 176 | Write-Verbose -Message "Connected to Web Reports Server: $($this.Server) (Version $($version.Results))" 177 | 178 | $this.State = 'Connected' 179 | } 180 | catch [System.Management.Automation.MethodInvocationException] { 181 | Write-Verbose -Message "Failed to connect to Web Reports Server: $($this.Server)" 182 | Write-Verbose -Message $PSItem.Exception.InnerException 183 | 184 | $this.State = 'Error' 185 | 186 | return $false 187 | } 188 | catch { 189 | Write-Verbose -Message "Failed to connect to Web Reports Server: $($this.Server)" 190 | 191 | $this.State = 'Error' 192 | 193 | return $false 194 | } 195 | 196 | return $true 197 | } 198 | 199 | $disconnect = { 200 | if ('Connected' -eq $this.State) { 201 | $this.State = 'Disconnected' 202 | 203 | Write-Verbose -Message "Disconnected from Web Reports Server: $($this.Server)" 204 | return $true 205 | } 206 | 207 | Write-Verbose -Message 'No established connection to a Web Reports Server was found!' 208 | return $false 209 | } 210 | 211 | $evaluate = { 212 | param( 213 | [Parameter( 214 | Mandatory = $true, 215 | Position = 0, 216 | HelpMessage = 'Session Relevance statement to evaluate' 217 | )] 218 | [ValidateNotNullOrEmpty()] 219 | [string]$Relevance, 220 | 221 | [Parameter( 222 | Mandatory = $false, 223 | Position = 1, 224 | HelpMessage = 'Array of strings representing the names for each resultant tuple field' 225 | )] 226 | [string[]]$FieldNames = $null 227 | ) 228 | 229 | Invoke-EvaluateSessionRelevance -Relevance $Relevance -Session $this -FieldNames $FieldNames 230 | } 231 | 232 | $session = $session | Add-Member -MemberType ScriptMethod -Name Connect -Value $connect -Force -PassThru 233 | $session = $session | Add-Member -MemberType ScriptMethod -Name Disconnect -Value $disconnect -Force -PassThru 234 | $session = $session | Add-Member -MemberType ScriptMethod -Name Evaluate -Value $evaluate -Force -PassThru 235 | 236 | $null = $session.Connect() 237 | 238 | if ('Error' -eq $session.State) { 239 | throw 'Unable to create a new WebReportsSession.' 240 | } 241 | 242 | $null = Set-Variable -Name WebReportsSession -Value $session -Scope Script -Force 243 | 244 | return $session 245 | } -------------------------------------------------------------------------------- /BigFix/Public/Set-WebReportsServer.ps1: -------------------------------------------------------------------------------- 1 | function Set-WebReportsServer { 2 | <# 3 | .Synopsis 4 | Sets the default Web Reports Server object. 5 | 6 | .Description 7 | Sets the default Web Reports Server object to use when calling New-WebReportsSession 8 | with the -Default switch. If the Web Reports Server object does not yet exist in 9 | the registry, then it will also be added. 10 | 11 | .Parameter Server 12 | Specifies the Web Reports Server object (created using New-WebReportsServer 13 | or returned from Get-WebReportsServer) to set as default. 14 | 15 | .Parameter Uri 16 | Specifies a well-formed absolute URI to the Web Reports Server to be set as the 17 | default. A new Web Reports Server object will be registered if one is not 18 | already found matching the URI. 19 | 20 | .Example 21 | # Sets the default Web Reports Session object to the Web Reports Server defined in 22 | # the $MyServer variable. 23 | Set-WebReportsServer -Server $MyServer 24 | 25 | .Example 26 | # Sets the default Web Reports Server object to the server 'webreports' over HTTPS, 27 | # creating and registering a new object if a matching one does not already exist. 28 | Set-WebReportsServer -Uri 'https://webreports/' 29 | 30 | #> 31 | [CmdletBinding(DefaultParameterSetName = 'URI')] 32 | Param( 33 | [Parameter( 34 | Mandatory = $true, 35 | Position = 0, 36 | ParameterSetName = 'SERVER', 37 | HelpMessage = 'Web Reports Server object for the Web Reports Server' 38 | )] 39 | [ValidateNotNull()] 40 | [PSTypeName('BigFix.WebReports.Server')]$Server, 41 | 42 | [Parameter( 43 | Mandatory = $true, 44 | Position = 0, 45 | ValueFromPipeline = $true, 46 | ParameterSetName = 'URI', 47 | HelpMessage = 'Well-formed absolute URI to the Web Reports Server (e.g. https://webreports/)' 48 | )] 49 | [ValidateScript( { Test-Uri -Uri $_ -Kind Absolute -Throw })] 50 | [string]$Uri 51 | ) 52 | 53 | Process { 54 | if ($PSCmdlet.ParameterSetName -eq 'URI') { 55 | $Server = New-WebReportsServer -Uri $Uri -NoPersist 56 | } 57 | 58 | $Servers = Get-Variable -Name WebReportsServers -ValueOnly -Scope Script -ErrorAction SilentlyContinue 59 | 60 | $found = $false 61 | foreach ($s in @($Servers)) { 62 | if ($s.Uri -eq $Server.Uri) { 63 | $found = $true 64 | $Server = $s 65 | break 66 | } 67 | } 68 | 69 | if ($found -eq $false) { 70 | $null = Set-Variable -Name WebReportsServers -Value @($Servers + $Server) -Scope Script -Force 71 | } 72 | 73 | $null = Set-Variable -Name WebReportsServersDefault -Value $Server -Scope Script -Force 74 | 75 | return $Server 76 | } 77 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019-2021 Promptus Software LLC 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # bigfix-powershell 2 | Integration module offering a consistent, simple, and streamlined approach to interacting with the BigFix suite of products and APIs directly from within PowerShell. 3 | 4 | # Getting Started 5 | Working with the BigFix PowerShell module starts with importing it into your PowerShell session. This is accomplished via the Import-Module command. 6 | 7 | ```powershell 8 | Import-Module BigFix 9 | ``` 10 | 11 | # Commands 12 | Commands provided in this module are broken up into functional groups. 13 | 14 | ## Web Reports Server 15 | When working with the Web Reports Server SOAP API, you will need to define the Web Reports Servers you plan on interacting with. The following commands are used for this purpose. 16 | 17 | ### New-WebReportsServer 18 | Creates a new Web Reports Server object to use when calling New-WebReportsSession, and [optionally] both registers and sets it as the default Web Reports Server object. 19 | 20 | #### Parameters 21 | **-Uri** Specifies a well-formed absolute URI to the Web Reports Server. 22 | 23 | **-Fqdn** Specifies the Fully Qualified Domain Name (FQDN) of the Web Reports Server. 24 | This can be entered either as just the hostname, IP address, or the FQDN (preferred). 25 | 26 | **-Port** Specifies the TCP port number of the Web Reports Server, if a non-standard (80/443) 27 | port is being used. 28 | **-Ssl** Switch specifying if SSL (HTTPS) is to be used when connecting to the Web Reports Server. 29 | 30 | **-NoPersist** Switch specifying that the Web Reports Server object created not be persisted to the 31 | registry nor set as the default. 32 | 33 | #### Examples 34 | Create a new Web Reports Server object to the server 'webreports' over HTTPS, using URI nomenclature. 35 | ```powershell 36 | New-WebReportsServer -Uri 'https://webreports/' 37 | ``` 38 | Output: 39 | ``` 40 | Uri Wsdl 41 | --- ---- 42 | https://webreports/ https://webreports/?wsdl 43 | ``` 44 | 45 | Create a new Web Reports Server object to the server 'webreports' over HTTPS, using URI nomenclature, and requesting it be non-persisted. 46 | ```powershell 47 | New-WebReportsServer -Uri 'https://webreports/' -NoPersist 48 | ``` 49 | Output: 50 | ``` 51 | Uri Wsdl 52 | --- ---- 53 | https://webreports/ https://webreports/?wsdl 54 | ``` 55 | 56 | Create a new Web Reports Server object to the server 'webreports' over HTTP on the default HTTP port (80). 57 | ```powershell 58 | New-WebReportsServer -Fqdn 'webreports' 59 | ``` 60 | Output: 61 | ``` 62 | Uri Wsdl 63 | --- ---- 64 | http://webreports/ http://webreports/?wsdl 65 | ``` 66 | 67 | Create a new Web Reports Server object to the server 'webreports' over HTTPS on the non-standard TCP port (8443) and request it to be non-persisted. 68 | ```powershell 69 | New-WebReportsServer -Fqdn 'webreports' -Port 8443 -Ssl -NoPersist 70 | ``` 71 | Output: 72 | ``` 73 | Uri Wsdl 74 | --- ---- 75 | https://webreports:8443/ https://webreports:8443/?wsdl 76 | ``` 77 | 78 | ### Get-WebReportsServer 79 | Gets registered Web Reports Server objects. When called without parameters, a listing of all registered Web Reports Server objects will be returned. If a URI is provided, attempt to return the matching Web Reports Server object. If called with the -Default switch, the registered default Web Reports Server object will be returned (if found). 80 | 81 | #### Parameters 82 | **-Uri** Specifies the well-formed absolute URI of the registered Web Reports Server object 83 | to return. 84 | 85 | **-Default** Switch specifying that the default registered Web Reports Server object is to be returned. 86 | 87 | #### Examples 88 | Get a listing of all registered Web Reports Server objects. 89 | ```powershell 90 | Get-WebReportsServer 91 | ``` 92 | Output: 93 | ``` 94 | Uri Wsdl 95 | --- ---- 96 | https://webreports/ https://webreports/?wsdl 97 | http://webreports/ http://webreports/?wsdl 98 | ``` 99 | 100 | Get the registered Web Reports Server object matching the Web Reports Server URI 'https://webreports/' 101 | ```powershell 102 | Get-WebReportsServer -Uri 'https://webreports/' 103 | ``` 104 | Output: 105 | ``` 106 | Uri Wsdl 107 | --- ---- 108 | https://webreports/ https://webreports/?wsdl 109 | 110 | ``` 111 | 112 | Get the default registered Web Reports Server object. 113 | ```powershell 114 | Get-WebReportsServer -Default 115 | ``` 116 | Output: 117 | ``` 118 | Uri Wsdl 119 | --- ---- 120 | http://webreports/ http://webreports/?wsdl 121 | ``` 122 | 123 | ### Set-WebReportsServer 124 | Sets the default Web Reports Server object to use when calling New-WebReportsSession with the -Default switch. If the Web Reports Server object does not yet exist in the registry, then it will also be added. 125 | 126 | #### Parameters 127 | **-Server** Specifies the Web Reports Server object (created using New-WebReportsServer 128 | or returned from Get-WebReportsServer) to set as default. 129 | **-Uri** Specifies a well-formed absolute URI to the Web Reports Server to be set as the 130 | default. A new Web Reports Server object will be registered if one is not 131 | already found matching the URI. 132 | 133 | #### Examples 134 | Sets the default Web Reports Session object to the Web Reports Server defined in the $MyServer variable. 135 | ```powershell 136 | $MyServer = New-WebReportsServer -Uri 'https://webreports/' 137 | 138 | Set-WebReportsServer -Server $MyServer 139 | ``` 140 | Output: 141 | ``` 142 | Uri Wsdl 143 | --- ---- 144 | https://webreports/ https://webreports/?wsdl 145 | ``` 146 | 147 | Sets the default Web Reports Server object to the server 'webreports' over HTTPS, creating and registering a new object if a matching one does not already exist. 148 | ```powershell 149 | Set-WebReportsServer -Uri 'https://webreports/' 150 | ``` 151 | Output: 152 | ``` 153 | Uri Wsdl 154 | --- ---- 155 | https://webreports/ https://webreports/?wsdl 156 | ``` 157 | 158 | ## Web Reports Session 159 | In addition to defining the Web Reports Server(s) you wish to interact with, you will need to establish a Web Reports Session to that server. The session is the heart of all the SOAP API helper commands as it is the communications change over which all interactions with the SOAP API are performed. 160 | 161 | Each Web Reports Session is self-contained allowing you to create multiple sessions to either a single Web Reports Server (i.e. session 1 uses account 'test' and session 2 uses account 'api'), or to a totally different Web Reports Server (i.e. consolidating data from multiple BigFix installations). 162 | 163 | ### New-WebReportsSession 164 | Creates a new Web Reports Session object exposing the BigFix Web Reports SOAP API. This session object is used by the other cmdlets in this module. 165 | 166 | #### Parameters 167 | **-Default** Use the default Web Reports Server previously defined to establish the session 168 | with. The default Web Reports Server is the last one created using 169 | New-WebReportsServer or Set-WebReportsServer. Get-WebReportsServer -Default will 170 | return the current default. 171 | 172 | **-Server** Specifies the Web Reports Server object (created using New-WebReportsServer 173 | or returned from Get-WebReportsServer) to establish the session with. 174 | 175 | **-Uri** Specifies a well-formed absolute URI to the Web Reports Server to establish 176 | the session with. A new Web Reports Server object will be registered 177 | if one is not already found matching the URI. 178 | 179 | **-Credential** Specifies the Web Reports account either as "myuser", "domain\myuser", or a 180 | PSCredential object. Omitting or providing a $null or 181 | [System.Management.Automation.PSCredential]::Empty will prompt the caller. 182 | 183 | #### Examples 184 | Create a Web Reports Session object to the default Web Reports Server, prompting for credentials. 185 | ```powershell 186 | New-WebReportsSession -Default 187 | ``` 188 | Output: 189 | ``` 190 | Windows PowerShell credential request. 191 | Please enter credentials for Web Reports Server 'https://webreports/' 192 | User: TestUser 193 | Password for user TestUser: ******** 194 | 195 | Server State Credential 196 | ------ ----- ---------- 197 | https://webreports/ Connected TestUser 198 | ``` 199 | 200 | Create a Web Reports Session object to the Web Reports Server defined in the $MyServer variable, prompting for credentials. 201 | ```powershell 202 | $MyServer = New-WebReportsServer -Uri 'http://webreports/' 203 | 204 | New-WebReportsSession -Server $MyServer 205 | ``` 206 | Output: 207 | ``` 208 | Windows PowerShell credential request. 209 | Please enter credentials for Web Reports Server 'http://webreports/' 210 | User: TestUser 211 | Password for user TestUser: ******** 212 | 213 | Server State Credential 214 | ------ ----- ---------- 215 | http://webreports/ Connected TestUser 216 | ``` 217 | 218 | Create a Web Reports Session object to the server 'webreports' over HTTPS, using the [PSCredential] credential object in the variable $credential. 219 | ```powershell 220 | $credential = Get-Credential 221 | 222 | New-WebReportsSession -Uri 'https://webreports/' -Credential $credential 223 | ``` 224 | Output: 225 | ``` 226 | cmdlet Get-Credential at command pipeline position 1 227 | Supply values for the following parameters: 228 | User: TestUser 229 | Password for user TestUser: ******** 230 | 231 | Server State Credential 232 | ------ ----- ---------- 233 | https://webreports/ Connected TestUser 234 | ``` 235 | 236 | ### Get-WebReportsSession 237 | Gets the Web Reports Session created during the last call to New-WebReportsSession. 238 | 239 | #### Examples 240 | ```powershell 241 | Get-WebReportsSession 242 | ``` 243 | Output: 244 | ``` 245 | Server State Credential 246 | ------ ----- ---------- 247 | https://webreports/ Connected TestUser 248 | ``` 249 | 250 | ### Invoke-EvaluateSessionRelevance 251 | Evaluates Session Relevance statements on the established Web Reports Session, parsing results into a more PowerShell-friendly format. Relevance Statements can be provided via the -Relevance parameter or the pipeline. Results are returned only after all Relevance Statements have completed. 252 | 253 | This function is also exposed directly on the Web Reports Session object as 'evaluate' which you can call. This object-based shortcut allows you to always ensure you are evaluating using an expected Web Reports Session. 254 | 255 | #### Parameters 256 | **-Relevance** Specifies the Session Relevance statement to evaluate on the Web Reports Session. 257 | 258 | **-Session** Specifies the Web Reports Session to evaluate the relevance on. If not provided, 259 | will attempt to use the last Web Reports Session created via 260 | New-WebReportsSession. 261 | 262 | **-FieldNames** Specifies a listing of field names to translate the evaluation tuple results 263 | into. 264 | 265 | #### Examples 266 | Evaluate the Session Relevance statement 'number of bes computers'. 267 | ```powershell 268 | Invoke-EvaluateSessionRelevance -Relevance 'number of bes computers' 269 | ``` 270 | Output: 271 | ``` 272 | Relevance Status Execution Time Evaluation Time Result Count Result 273 | --------- ------ -------------- --------------- ------------ ------ 274 | number of bes computers Success 00:00:00.3917915 00:00:00 1 4 275 | ``` 276 | 277 | Evaluate the Session Relevance statement '(id of it, last report time of it) of bes computers', parsing results into objects with the field names 'Id' and 'LastReportTime'. 278 | ```powershell 279 | Invoke-EvaluateSessionRelevance -Relevance '(id of it, last report time of it) of bes computers' -FieldNames @('Id', 'LastReportTime') 280 | 281 | Invoke-EvaluateSessionRelevance -Relevance '(id of it, last report time of it) of bes computers' -FieldNames @('Id', 'LastReportTime') | Select-Object -ExpandProperty Results 282 | ``` 283 | Output: 284 | ``` 285 | Relevance Status Execution Time Evaluation Time Result Count Result 286 | --------- ------ -------------- --------------- ------------ ------ 287 | (id of it, last report time of it) of bes computers Success 00:00:00.1223545 00:00:00 4 {@{Id=1036828; Last... 288 | 289 | Id LastReportTime 290 | -- -------------- 291 | 1036828 3/19/2019 4:44:00 PM 292 | 551884969 3/19/2019 4:45:28 PM 293 | 1614275947 3/19/2019 4:53:41 PM 294 | 1625012524 3/19/2019 4:38:53 PM 295 | ``` 296 | 297 | ## Qna Session 298 | Working with remote Web Reports Server(s) is great but sometimes you may want to evaluate client relevance directly on the computer you are currently connected to. This can be as simple as firing off simple relevance statements to obtain answers that would be otherwise more complicated to obtain, or as complex as building a full offline fixlet evaluation system to determine what fixlets the computer requires without requiring a network connection or even a full BigFix Client instance. 299 | 300 | Each Qna Session is self-contained allowing you to create multiple sessions to either a single qna.exe binary (for parallel query executions), or to a totally different qna.exe binary (testing queries for consistent results across multiple versions). 301 | 302 | ### New-QnaSession 303 | Creates a new Qna Session object and expose it into the current scope. By default, it will attempt to link to the qna.exe utility application binary using the following search path order: 304 | 1. Directory defined within the environmental variable 'QnA'. 305 | 2. Current working directory. 306 | 3. Directory where the BigFix Client is registered 307 | 4. Every directory defined within the environmental variable 'PATH', in the order it is defined. 308 | 309 | If called with the -ExecutablePath parameter and provided with the full path of the qna.exe utility, the session will attempt to link to that binary. 310 | 311 | #### Parameters 312 | **-ExecutablePath** Path to the BigFix Qna utility executable (i.e. qna.exe) 313 | #### Examples 314 | Create a new Qna Session using the qna.exe utility application installed as part of the BigFix Client installation. 315 | ```powershell 316 | New-QnaSession 317 | ``` 318 | Output: 319 | ``` 320 | IdleTimeout EvaluationTimeout ExecutablePath Version 321 | ----------- ----------------- -------------- ------- 322 | 300 60 C:\Program Files (x86)\BigFix Enterprise\BES Client\qna.exe 9.5.12.68 323 | ``` 324 | 325 | Create a new Qna Session using the qna.exe utility application at the provided path. 326 | ```powershell 327 | New-QnaSession -ExecutablePath 'C:\Tools\BigFix\qna.exe' 328 | ``` 329 | Output: 330 | ``` 331 | IdleTimeout EvaluationTimeout ExecutablePath Version 332 | ----------- ----------------- -------------- ------- 333 | 300 60 C:\Tools\BigFix\qna.exe 9.5.15.71 334 | ``` 335 | 336 | ### Get-QnaSession 337 | Gets the previously instantiated Qna Session object. 338 | 339 | #### Examples 340 | ```powershell 341 | Get-QnaSession 342 | ``` 343 | Output: 344 | ``` 345 | IdleTimeout EvaluationTimeout ExecutablePath Version 346 | ----------- ----------------- -------------- ------- 347 | 300 60 C:\Program Files (x86)\BigFix Enterprise\BES Client\qna.exe 9.5.12.68 348 | ``` 349 | ### Invoke-EvaluateClientRelevance 350 | Evaluates Client Relevance statements in the established Qna Session, parsing results into a more PowerShell-friendly format. Relevance Statements can be provided via the -Relevance parameter or the pipeline. Results are returned sequentially to the pipeline as they are evaluated in the Qna Session. 351 | 352 | #### Parameters 353 | **-Relevance** Specifies the Client Relevance statement(s) to evaluate in the Qna Session. 354 | 355 | **-Session** Specifies the Qna Session to evaluate the relevance in. If not provided, 356 | will attempt to use the last Qna Session created via New-QnaSession, creating 357 | a new Qna Session in the event none exists. 358 | 359 | #### Examples 360 | Evaluate the Client Relevance statement 'computer name'. 361 | ```powershell 362 | Invoke-EvaluateClientRelevance -Relevance 'computer name' 363 | ``` 364 | Output: 365 | ``` 366 | Relevance Answer Error EvalTime 367 | --------- ------ ----- -------- 368 | computer name {bigfix} 169 369 | ``` 370 | 371 | Evaluate the Client Relevance statements 'now' and 'version of client' using the pipeline for input. 372 | ```powershell 373 | 'now','version of client' | Invoke-EvaluateClientRelevance 374 | ``` 375 | Output: 376 | ``` 377 | Relevance Answer Error EvalTime 378 | --------- ------ ----- -------- 379 | now {Sun, 23 May 2021 15:52:15 -0400} 89 380 | version of client {9.5.12.68} 695 381 | ``` 382 | 383 | Evaluate the Client Relevance statement 'computer name' using a specific Qna Session. 384 | ```powershell 385 | $QnaSession = New-QnaSession -ExecutablePath 'C:\Tools\BigFix\qna.exe' 386 | Invoke-EvaluateClientRelevance -Relevance 'computer name' -Session $QnaSession 387 | ``` 388 | Output: 389 | ``` 390 | Relevance Answer Error EvalTime 391 | --------- ------ ----- -------- 392 | computer name {bigfix} 188 393 | ``` 394 | --------------------------------------------------------------------------------