Skip to content

aldrichtr/infraspective

Repository files navigation

Status Location Version
Under Development (Pre-release)
0.4.12

infraspective : Infrastructure Testing with PowerShell

Current status

PSScriptAnalyzer results Pester unit tests

Synopsis

infraspective is a PowerShell module for testing (auditing, validating) infrastructure using the Pester Testing Module

Description

infraspective reads tests (written in BDD style , like Pester) and produces output that reports on compliance of your infrastructure to those tests.

Predecessors

Originally, Operation Validation Framework used Pester tests organized in particular directories in your module. poshspec added a DSL for making those tests more expressive. infraspective picks up where they left off, using modern Pester (there were some breaking changes from v4 to v5) and adds in some concepts from other tools to create a Policy as Code tool.

Starting with a test like:

Describe "Services" {
    It "DNS Service should be running" {
        $dns_service = Get-Service -Name 'DNS'
        $dns_service.Status | Should -Be Running
    }
}

poshspec gave us the ability to write this like:

Describe "Services" {
    Service DNS Status { Should -Be Running }
    # i fixed it up for v5 a little
}

infraspective picks up where these left off.

Additional language features

At this time infraspective adds four new structures to organize and classify tests:

  • Control
  • Grouping
  • Checklist
  • Include

Control

A Control is 0 or more tests + metadata. If you have experience with NIST STIGs then this example might look familiar:

Control "SV-220697r569187_rule" -Resource "Windows" -Impact "medium" -Reference 'CCI:000366'-Title (
    "Domain-joined systems must use Windows 10 Enterprise Edition 64-bit version.") -Description (
        "Credential Guard use virtualization based security to protect...") {
            Describe "Verify domain-joined systems are the proper version" {
                BeforeAll {
                    $v = Get-WindowsVersion
                }
                It "Should be Windows 10" {
                    $v.ProductName | Should -match '^Windows 10'
                }
                It "Should be Enterprise Edition" {
                    $v.EditionID | Should -match 'Enterprise'
                }
                It "Should be 64 bit" {
                    [Environment]::Is64BitOperatingSystem | Should -BeTrue
                }
            }
        }

Grouping

A Grouping is a logical collection of 0 or more Groupings and or Controls. Meaning Groupings can be nested to provide whatever structure you need. Continuing our Windows 10 STIG example:

Grouping "V-220697" -Title "SRG-OS-000480-GPOS-00227" {
    Control "SV-220697r569187_rule" -Resource "Windows" -Impact "medium" -Reference 'CCI:000366'-Title (
        "Domain-joined systems must use Windows 10 Enterprise Edition 64-bit version.") -Description (
            "Credential Guard use virtualization based security to protect...") {
                Describe "Verify domain-joined systems are the proper version" {
                    BeforeAll {
                        $v = Get-WindowsVersion
                    }
                    It "Should be Windows 10" {
                        $v.ProductName | Should -match '^Windows 10'
                    }
                    It "Should be Enterprise Edition" {
                        $v.EditionID | Should -match 'Enterprise'
                    }
                    It "Should be 64 bit" {
                        [Environment]::Is64BitOperatingSystem | Should -BeTrue
                    }
                }
            }
}

Checklist

Next, one or more Controls together create a Checklist. A Checklist is a collection of Controls that define a given audit criteria. Since we are already using the example so far, a Checklist would be analogous to the Windows 10 STIG Version 2

Checklist "MS Windows 10 STIG V2R3" -Title "Microsoft Windows 10 Security Technical Implementation Guide" -Version
'3.2.2.36079' {
    Grouping "V-220697" -Title "SRG-OS-000480-GPOS-00227" {
        Control "SV-220697r569187_rule" -Resource "Windows" -Impact "medium" -Reference 'CCI:000366'-Title (
            "Domain-joined systems must use Windows 10 Enterprise Edition 64-bit version.") -Description (
                "Credential Guard use virtualization based security to protect...") {
                    Describe "Verify domain-joined systems are the proper version" {
                        BeforeAll {
                            $v = Get-WindowsVersion
                        }
                        It "Should be Windows 10" {
                            $v.ProductName | Should -match '^Windows 10'
                        }
                        It "Should be Enterprise Edition" {
                            $v.EditionID | Should -match 'Enterprise'
                        }
                        It "Should be 64 bit" {
                            [Environment]::Is64BitOperatingSystem | Should -BeTrue
                        }
                    }
                }
    }
}

Include

An organizational function, Include allows you to define Checklists, Groups, Controls, and tests in separate files which can then be executed at run time at the place that you include them from, like this:

Checklist "A well organized checklist" -Version "1.0" {
    Include -Path "controls" -Filter "*.Control.ps1" -Recurse
}

Include supports most of the relevant Get-ChildItem parameters:

-Path (this is relative to the path of the file that `Include` was called from)
-Filter
-Include
-Exclude
-FollowSymlinks
-Recurse

Notes

In keeping with Pester's convention of a directory of files name *.Tests.ps1, infraspective looks for files named *.Audit.ps1

Example

Import-Module infraspective
Invoke-Infraspective

infraspective output