Notices: This section not yet converted to new layout. Download stats are rolling back out.

This is not the latest version of Pester available.

Pester

4.7.0

Package test results are passing.

This package was approved as a trusted package on 3/3/2019.

Pester provides a framework for running BDD style Tests to execute and validate PowerShell commands inside of PowerShell and offers a powerful set of Mocking Functions that allow tests to mimic and mock the functionality of any command inside of a piece of PowerShell code being tested. Pester tests can execute any command or script that is accessible to a pester test file. This can include functions, Cmdlets, Modules and scripts. Pester can be run in ad hoc style in a console or it can be integrated into the Build scripts of a Continuous Integration system.

To install Pester, run the following command from the command line or from PowerShell:

C:\> choco install pester --version 4.7.0

To upgrade Pester, run the following command from the command line or from PowerShell:

C:\> choco upgrade pester --version 4.7.0

Files

Hide
  • tools\Functions\Assertions\BeIn.ps1 Show
    function Should-BeIn($ActualValue, $ExpectedValue, [switch] $Negate, [string] $Because) {
        <#
    .SYNOPSIS
    Asserts that a collection of values contain a specific value.
    Uses PowerShell's -contains operator to confirm.
    
    .EXAMPLE
    1 | Should -BeIn @(1,2,3,'a','b','c')
    This test passes, as 1 exists in the provided collection.
    #>
        [bool] $succeeded = $ExpectedValue -contains $ActualValue
        if ($Negate) {
            $succeeded = -not $succeeded
        }
    
        if (-not $succeeded) {
            if ($Negate) {
                return New-Object psobject -Property @{
                    Succeeded      = $false
                    FailureMessage = "Expected collection $(Format-Nicely $ExpectedValue) to not contain $(Format-Nicely $ActualValue),$(Format-Because $Because) but it was found."
                }
            }
            else {
                return New-Object psobject -Property @{
                    Succeeded      = $false
                    FailureMessage = "Expected collection $(Format-Nicely $ExpectedValue) to contain $(Format-Nicely $ActualValue),$(Format-Because $Because) but it was not found."
                }
            }
        }
    
        return New-Object psobject -Property @{
            Succeeded = $true
        }
    }
    
    Add-AssertionOperator -Name         BeIn `
        -InternalName Should-BeIn `
        -Test         ${function:Should-BeIn}
    
    
    function ShouldBeInFailureMessage() {
    }
    function NotShouldBeInFailureMessage() {
    }
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUs/T5jprtM3OEJ8vvRjOKIfeX
    # Da6ggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # YaHuvfpWuOwVwsNLtC5F63HhYOYwDQYJKoZIhvcNAQEBBQAEggEACmRmBZt27wPj
    # 0C0+ToHJsoD1VyL4gTS6VwxH3dNz021vmn9xMDjSPvzjSaBbBNSa1eO/YC7FWmqR
    # zrf2JIhbkc3i4EWQpAkwEThITvbWfID81CHYaympA2mAUxeNQy4sf+khldm8TqEq
    # gJTF25QprG5wplDGJEgiaB5rFH0fu7tr/mDo3g9Ql8frmY3g8VCKZekctm9Z1z6T
    # UayUg0WWaxW4JmmBztPOk5lH+KZFo6x/6EoyzWqOG2nSai4839nYpAIv4EtlgIh3
    # N8c8L0RzE5CF7fknoYAj++6sATSLZ9J3rLv70SJRvr4ZnGEUvCMVNzs2tRIxVZgk
    # Aw0jH0Lf9aGCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzQ5WjAjBgkqhkiG9w0BCQQx
    # FgQUiJ06Jz6qHR71LMuhvzGIYI6XKy8wDQYJKoZIhvcNAQEBBQAEggEALqfi7Vd6
    # zmvObjq2eCqBY31/U81jqBBs+RdKfkzUCaKfRNuGB7UW5ITMU/326NLrUb9PEh2X
    # VnwQA1qD5b2+4EEc1txrFf2BKiOdjfTQj99dR1bLs5XqFxpQVg7ufCBAdt2rwVnT
    # aayusx474rWCHFfm4OMAB8bPLkEh/DOfEFvSbvdfA9DzNOdB+VpJalqngCn4YsE3
    # 6aRWyFZQKTZlQEOQ+Tf+oy99Qwr5/C/Lsk5UV4vxHs3bqIx3QkWTqTgqPgt8YgUc
    # OUs3xOMOd0W2Z14L8H1ihMg4UDNmJvi8flSdHbeJpbEwfEYVnh1J1zublsvFXgWU
    # d47qrq8FQd/99w==
    # SIG # End signature block
    
  • tools\Functions\Assertions\BeLessThan.ps1 Show
    function Should-BeLessThan($ActualValue, $ExpectedValue, [switch] $Negate, [string] $Because) {
        <#
    .SYNOPSIS
    Asserts that a number (or other comparable value) is lower than an expected value.
    Uses PowerShell's -lt operator to compare the two values.
    
    .EXAMPLE
    1 | Should -BeLessThan 10
    This test passes, as PowerShell evaluates `1 -lt 10` as true.
    #>
        if ($Negate) {
            return Should-BeGreaterOrEqual -ActualValue $ActualValue -ExpectedValue $ExpectedValue -Negate:$false -Because $Because
        }
    
        if ($ActualValue -ge $ExpectedValue) {
            return New-Object psobject -Property @{
                Succeeded      = $false
                FailureMessage = "Expected the actual value to be less than $(Format-Nicely $ExpectedValue),$(Format-Because $Because) but got $(Format-Nicely $ActualValue)."
            }
        }
    
        return New-Object psobject -Property @{
            Succeeded = $true
        }
    }
    
    
    function Should-BeGreaterOrEqual($ActualValue, $ExpectedValue, [switch] $Negate, [string] $Because) {
        <#
    .SYNOPSIS
    Asserts that a number (or other comparable value) is greater than or equal to an expected value.
    Uses PowerShell's -ge operator to compare the two values.
    
    .EXAMPLE
    2 | Should -BeGreaterOrEqual 0
    This test passes, as PowerShell evaluates `2 -ge 0` as true.
    
    .EXAMPLE
    2 | Should -BeGreaterOrEqual 2
    This test also passes, as PowerShell evaluates `2 -ge 2` as true.
    #>
        if ($Negate) {
            return Should-BeLessThan -ActualValue $ActualValue -ExpectedValue $ExpectedValue -Negate:$false -Because $Because
        }
    
        if ($ActualValue -lt $ExpectedValue) {
            return New-Object psobject -Property @{
                Succeeded      = $false
                FailureMessage = "Expected the actual value to be greater than or equal to $(Format-Nicely $ExpectedValue),$(Format-Because $Because) but got $(Format-Nicely $ActualValue)."
            }
        }
    
        return New-Object psobject -Property @{
            Succeeded = $true
        }
    }
    
    Add-AssertionOperator -Name         BeLessThan `
        -InternalName Should-BeLessThan `
        -Test         ${function:Should-BeLessThan} `
        -Alias        'LT'
    
    Add-AssertionOperator -Name         BeGreaterOrEqual `
        -InternalName Should-BeGreaterOrEqual `
        -Test         ${function:Should-BeGreaterOrEqual} `
        -Alias        'GE'
    
    #keeping tests happy
    function ShouldBeLessThanFailureMessage() {
    }
    function NotShouldBeLessThanFailureMessage() {
    }
    
    function ShouldBeGreaterOrEqualFailureMessage() {
    }
    function NotShouldBeGreaterOrEqualFailureMessage() {
    }
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUyW7BoYLN+rhkh0Age/nVi7Ed
    # gACggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # JD1IbGhBmTLV3Gy57mDAMLQvQe8wDQYJKoZIhvcNAQEBBQAEggEAdlJOWBo+TZsL
    # 7FZNQkcbSEiPiUlBU10wz2qAXFNQwTfasZbJ32vWRX37rE9ZfCmsoJR0XRRqA8QC
    # FHKZKrwYrxjr2Y7Fbc384fb5qR9S7O8lGY4tpa0VjdEdURuGyE8aI/spFqMfWLHD
    # hFMQF1/qZoqXUn/sjKbrsuCPnptvlKpdW3O4yqIK9rArnqrF6eBOPciyL48mKZ8E
    # G749VoecsmAeIjtq8d1ot8/re6O/6FbViSh34mUW429HAYZqzCpji7AwtCDrEdG0
    # UDzxthtyhfzKATAg2iZt9oS/uOdWgybLa3rVw9EOpvnz4AZsn1lVoyAkOeuYnIBf
    # IZXn1Yc5U6GCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzQ5WjAjBgkqhkiG9w0BCQQx
    # FgQUPoZa6L+bl7bcqFj+i4OjETXL1mgwDQYJKoZIhvcNAQEBBQAEggEAQ4fFCrVe
    # c1FFIOP6NXJwqrzjKaw00pq4z8DQ0OeJ3lQQuKZXlyGfzxEZnsHYk20lvM6OYWLb
    # Hl5aki6O1D/bXXn6tyCdDm9rrel8tmFQ8GsHdSZ7eWsES8ClAeUZMHcIzD6oGQmJ
    # EFMXQbqQQwCAT6En3fHisAfFA7WJ3mg78o/Qv48XRaJEO5s6bZHHXX5hpiaDIHsp
    # B3mjj9vc4fgxwq2n6T/mOdUO7/5tV5Xu2QQIY51vTISmfvl9dXw1qhmdUE9BEM5y
    # fvcWoyzWmjk/n80W5+SQQdG50ePOkoEuiBYp642Xo3mPgzw/AiC+oij64yzdOehi
    # R030nFKCNytpCg==
    # SIG # End signature block
    
  • tools\Functions\Assertions\BeLike.ps1 Show
    function Should-BeLike($ActualValue, $ExpectedValue, [switch] $Negate, [String] $Because) {
        <#
    .SYNOPSIS
    Asserts that the actual value matches a wildcard pattern using PowerShell's -like operator.
    This comparison is not case-sensitive.
    
    .EXAMPLE
    $actual = "Actual value"
    PS C:\>$actual | Should -BeLike "actual *"
    
    This test will pass. -BeLike is not case sensitive.
    For a case sensitive assertion, see -BeLikeExactly.
    
    .EXAMPLE
    $actual = "Actual value"
    PS C:\>$actual | Should -BeLike "not actual *"
    
    This test will fail, as the first string does not match the expected value.
    #>
        [bool] $succeeded = $ActualValue -like $ExpectedValue
        if ($Negate) {
            $succeeded = -not $succeeded
        }
    
        if (-not $succeeded) {
            if ($Negate) {
                return New-Object psobject -Property @{
                    Succeeded      = $false
                    FailureMessage = "Expected like wildcard $(Format-Nicely $ExpectedValue) to not match $(Format-Nicely $ActualValue),$(Format-Because $Because) but it did match."
                }
            }
            else {
                return New-Object psobject -Property @{
                    Succeeded      = $false
                    FailureMessage = "Expected like wildcard $(Format-Nicely $ExpectedValue) to match $(Format-Nicely $ActualValue),$(Format-Because $Because) but it did not match."
                }
            }
        }
    
        return New-Object psobject -Property @{
            Succeeded = $true
        }
    }
    
    Add-AssertionOperator -Name         BeLike `
        -InternalName Should-BeLike `
        -Test         ${function:Should-BeLike}
    
    function ShouldBeLikeFailureMessage() {
    }
    function NotShouldBeLikeFailureMessage() {
    }
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQU6f9XPmKmwDLM97pqTMzyNbwa
    # Eu2ggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # y7PzHcHZJuN12P8f5w8nlJyfugkwDQYJKoZIhvcNAQEBBQAEggEAYNWPeODnnIRs
    # DhgD01G4RXNVx3KMC4TpLx+wa9VlWyn1omo5uwZYfhAMqdMBWI+aK1kIrePrC8MU
    # F7BdI1RSLMn82278Qh0fCVwJpv1GtE13YdusdX11sa07nR4p3T22Uc5IZyUzD+gs
    # utWsXpvg5Af/yP2BTC9FK6U0KFgImwCbB87NgdexlWaPv5ZhyUnRgDa6JAlwHej7
    # +bZUm57R7VYxgA73/babm3MrvY3pflpjht+wlo230zW9sTkHPoRi3nrt5pMMuhWR
    # jw5xAY5AKhpNX3GTLj8keXmgjkln9L5bChiMdjNWjI6G2cKKY5CckdobAxyDd0n7
    # W7KAtp0aMaGCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzUwWjAjBgkqhkiG9w0BCQQx
    # FgQUZfF2KAiRaO99naAjauHUNHVf1KcwDQYJKoZIhvcNAQEBBQAEggEAePTuWQ8p
    # KNKYVUrQJF0iYuW5F70/mQy9r0NbXjJ3srG/d1SVm0AxZTKWWtpiSWxFkAZWGlrl
    # FajUotrQ2CchpjdZmEeyZ+npI5yDsLrLU2P3IrezJqKNx3l1M939s1ncfNtRORdG
    # RJIHAGapJiw1qgMt51f2o2cTapGwrcsw/4+wSk6btayrjr6OWKZ7AA9Ub/CjsRf8
    # eGSBbFEyg3G88GUAl+3e9c6BHoK1cAPK/Wx3KIkg9Zv4Tpp3szwucn2lXAN/2KWN
    # RtgiotEsXAShHv0/m984zkzcfS85DlYF5mUdMKBxzLe06Fc0eOIktzZDuK5aOHRR
    # nPb0vITU9IggjQ==
    # SIG # End signature block
    
  • tools\Functions\Assertions\BeLikeExactly.ps1 Show
    function Should-BeLikeExactly($ActualValue, $ExpectedValue, [switch] $Negate, [String] $Because) {
        <#
    .SYNOPSIS
    Asserts that the actual value matches a wildcard pattern using PowerShell's -like operator.
    This comparison is case-sensitive.
    
    .EXAMPLE
    $actual = "Actual value"
    PS C:\>$actual | Should -BeLikeExactly "Actual *"
    
    This test will pass, as the string matches the provided pattern.
    
    .EXAMPLE
    $actual = "Actual value"
    PS C:\>$actual | Should -BeLikeExactly "actual *"
    
    This test will fail, as -BeLikeExactly is case-sensitive.
    #>
        [bool] $succeeded = $ActualValue -clike $ExpectedValue
        if ($Negate) {
            $succeeded = -not $succeeded
        }
    
        if (-not $succeeded) {
            if ($Negate) {
                return New-Object psobject -Property @{
                    Succeeded      = $false
                    FailureMessage = "Expected case sensitive like wildcard $(Format-Nicely $ExpectedValue) to not match $(Format-Nicely $ActualValue),$(Format-Because $Because) but it did match."
                }
            }
            else {
                return New-Object psobject -Property @{
                    Succeeded      = $false
                    FailureMessage = "Expected case sensitive like wildcard $(Format-Nicely $ExpectedValue) to match $(Format-Nicely $ActualValue),$(Format-Because $Because) but it did not match."
                }
            }
        }
    
        return New-Object psobject -Property @{
            Succeeded = $true
        }
    }
    
    Add-AssertionOperator -Name         BeLikeExactly `
        -InternalName Should-BeLikeExactly `
        -Test         ${function:Should-BeLikeExactly}
    
    function ShouldBeLikeExactlyFailureMessage() {
    }
    function NotShouldBeLikeExactlyFailureMessage() {
    }
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUGJ7sabsKt3Vkj8a6oqPBASOC
    # anmggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # YhlkYZgQPknKMWSAO0Nr66BhuvowDQYJKoZIhvcNAQEBBQAEggEAlIFZoBqtk+8u
    # 7O28sj9jHuJO/XNwwyDNnovlGFveovITcCVN+MjD8vrQM2VG92mul4rZIJymGJJq
    # Kg5MH6I91OhVRp0YhLBRcaZLN52UxOskgbzQEgN865ULO5uZUgicD5JEyL3tWUCU
    # Ondjv0Mm3wurUpXGYIv5AtKQvRkJ9XGw/D3GXxRcOpZf3X96rM0NyLQDQbr3GY/N
    # XFB66v/E17xZfBlYfjRXFbKvzdYP6zqXGa1gos5OSAjbnwfKHXfwpY3hXl+b/vU8
    # ieCPMGt/sFI5/8ICNkmPQaAGcfdXnDveDsVGTEHPolWzNyjw9RmfnKLJzpaUcmy9
    # Fm/qiFFvx6GCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzUxWjAjBgkqhkiG9w0BCQQx
    # FgQUg7XreDxsbv2f6fVT6Xo3+1FZHrgwDQYJKoZIhvcNAQEBBQAEggEAcLa2LTtb
    # lTHJml3NgqmqxcIK0XNzSt9QR2Hf8qCh+w3hV4ZWspqyWCCRcLCU1ixF6jtKNMhy
    # BAbenc7b1GlSBatpMtWYOn42qAFl8x/bEkLJpTzoLVpzE8VzhQAZGS/2M8Yk+adz
    # 7bDhfoLOtDPFE1OaLaApX8wOA+hAosGRCMwT4QyS66IdP3OKcptOkMHbX/UxbYIU
    # vN5uS/f3yOs5KFdK62IrHG+ajp7fEVsvjKBpouthf30eUkBHWYnqhSkHUXPwn6tu
    # UH+wPZ+HeqAL/rRwE4YcfHvBGimbDxUDZW3QQhvroHaZS+03UtdY0x1PWCDnop9B
    # g9nw+Qp7ypzwqQ==
    # SIG # End signature block
    
  • tools\Functions\Assertions\BeNullOrEmpty.ps1 Show
    function Should-BeNullOrEmpty([object[]] $ActualValue, [switch] $Negate, [string] $Because) {
        <#
    .SYNOPSIS
    Checks values for null or empty (strings).
    The static [String]::IsNullOrEmpty() method is used to do the comparison.
    
    .EXAMPLE
    $null | Should -BeNullOrEmpty
    This test will pass. $null is null.
    
    .EXAMPLE
    $null | Should -Not -BeNullOrEmpty
    This test will fail and throw an error.
    
    .EXAMPLE
    @() | Should -BeNullOrEmpty
    An empty collection will pass this test.
    
    .EXAMPLE
    ""  | Should -BeNullOrEmpty
    An empty string will pass this test.
    #>
        if ($null -eq $ActualValue -or $ActualValue.Count -eq 0) {
            $succeeded = $true
        }
        elseif ($ActualValue.Count -eq 1) {
            $expandedValue = $ActualValue[0]
            if ($expandedValue -is [hashtable]) {
                $succeeded = $expandedValue.Count -eq 0
            }
            else {
                $succeeded = [String]::IsNullOrEmpty($expandedValue)
            }
        }
        else {
            $succeeded = $false
        }
    
        if ($Negate) {
            $succeeded = -not $succeeded
        }
    
        $failureMessage = ''
    
        if (-not $succeeded) {
            if ($Negate) {
                $failureMessage = NotShouldBeNullOrEmptyFailureMessage -Because $Because
            }
            else {
                $failureMessage = ShouldBeNullOrEmptyFailureMessage -ActualValue $ActualValue -Because $Because
            }
        }
    
        return New-Object psobject -Property @{
            Succeeded      = $succeeded
            FailureMessage = $failureMessage
        }
    }
    
    function ShouldBeNullOrEmptyFailureMessage($ActualValue, $Because) {
        return "Expected `$null or empty,$(Format-Because $Because) but got $(Format-Nicely $ActualValue)."
    }
    
    function NotShouldBeNullOrEmptyFailureMessage ($Because) {
        return "Expected a value,$(Format-Because $Because) but got `$null or empty."
    }
    
    Add-AssertionOperator -Name               BeNullOrEmpty `
        -InternalName       Should-BeNullOrEmpty `
        -Test               ${function:Should-BeNullOrEmpty} `
        -SupportsArrayInput
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUoxNz23ji+jAAzt+ouf+RJFYR
    # qOmggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # x238ZpWezo9rROdntXYzS/CzyJMwDQYJKoZIhvcNAQEBBQAEggEAksKEzZ7YYj3K
    # rIXN3GN9rNvCh3xWUAKbckG8UB+sK8ntZ86wUiwIawLhPc5orsdmrkyVbQwkrXim
    # iSvaIFMOkz8VP4yzBnX8dfBZ1FyS0AZJwyO0NmrXKSiMwmiBigvP+ZZ2OZF3C3xo
    # N4F4nDLhUT3Vn+mqp2kt/VZKZhetnDc4rdvwiSYS6QtxlZaLKI8820/KjtSq9jeZ
    # CzOvzYcREK/GuigHPGUwb/5UyBj6O+TpG6oA2Ox5YBUlXk2Hpbn+BB+TraT2qQ7V
    # pYy0sh6qq5HGTc5yFJVUoO61B1L3N2RGSNYFym7jIts9SIhe2CYWYy0bA5SpZCl3
    # gjLH/V2Xw6GCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzUxWjAjBgkqhkiG9w0BCQQx
    # FgQUVw9gAqUcdnf3rKO6kBEbHkb6DUYwDQYJKoZIhvcNAQEBBQAEggEAU2V5pb6V
    # bVAm16x4v8YhSdxDaQ1PE9iQLllC2glCd69tD6q3rgZ6qjneygeEzdW3d3VpZprO
    # zTQxIf4XzNhj8BABAU3Znf7qYS8yOoF4i4osMSUiZd3ciXCz/FGY1heoUFiLLq0+
    # 6FAdFSp7ph2in7CQEyIrSpPoeHK/f/+mxPxBm6Nwjrvw2ffqXp9CZrRLNQuin26L
    # alRdJmGctSLwFkdemZ+OjSjVIMiJXfVlv665GCyOC+3V99igryhE8Xb9An9ItZ8b
    # OagKYLsb7Ps7Ys1FGZiTtFCsaJTIrLaIptawxBJMNsjeK9yVy54KonmmkkpCjYbK
    # M4WqE0vRZq9PFA==
    # SIG # End signature block
    
  • tools\Functions\Assertions\BeOfType.ps1 Show
    function Should-BeOfType($ActualValue, $ExpectedType, [switch] $Negate, [string]$Because) {
        <#
    .SYNOPSIS
    Asserts that the actual value should be an object of a specified type
    (or a subclass of the specified type) using PowerShell's -is operator.
    
    .EXAMPLE
    $actual = Get-Item $env:SystemRoot
    PS C:\>$actual | Should -BeOfType System.IO.DirectoryInfo
    
    This test passes, as $actual is a DirectoryInfo object.
    
    .EXAMPLE
    $actual | Should -BeOfType System.IO.FileSystemInfo
    This test passes, as DirectoryInfo's base class is FileSystemInfo.
    
    .EXAMPLE
    $actual | Should -HaveType System.IO.FileSystemInfo
    This test passes for the same reason, but uses the -HaveType alias instead.
    
    .EXAMPLE
    $actual | Should -BeOfType System.IO.FileInfo
    This test will fail, as FileInfo is not a base class of DirectoryInfo.
    #>
        if ($ExpectedType -is [string]) {
            # parses type that is provided as a string in brackets (such as [int])
            $parsedType = ($ExpectedType -replace '^\[(.*)\]$', '$1') -as [Type]
            if ($null -eq $parsedType) {
                throw [ArgumentException]"Could not find type [$ParsedType]. Make sure that the assembly that contains that type is loaded."
            }
    
            $ExpectedType = $parsedType
        }
    
        $succeded = $ActualValue -is $ExpectedType
        if ($Negate) {
            $succeded = -not $succeded
        }
    
        $failureMessage = ''
    
        if ($null -ne $ActualValue) {
            $actualType = $ActualValue.GetType()
        }
        else {
            $actualType = $null
        }
    
        if (-not $succeded) {
            if ($Negate) {
                $failureMessage = "Expected the value to not have type $(Format-Nicely $ExpectedType) or any of its subtypes,$(Format-Because $Because) but got $(Format-Nicely $ActualValue) with type $(Format-Nicely $actualType)."
            }
            else {
                $failureMessage = "Expected the value to have type $(Format-Nicely $ExpectedType) or any of its subtypes,$(Format-Because $Because) but got $(Format-Nicely $ActualValue) with type $(Format-Nicely $actualType)."
            }
        }
    
        return New-Object psobject -Property @{
            Succeeded      = $succeded
            FailureMessage = $failureMessage
        }
    }
    
    
    Add-AssertionOperator -Name         BeOfType `
        -InternalName Should-BeOfType `
        -Test         ${function:Should-BeOfType} `
        -Alias        'HaveType'
    
    function ShouldBeOfTypeFailureMessage() {
    }
    
    function NotShouldBeOfTypeFailureMessage() {
    }
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUIMk8guo3eGnuj5/U11/rTf3E
    # F0OggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # 4LZIp1z4/pT2h7BM6jTqUXjH/+IwDQYJKoZIhvcNAQEBBQAEggEALs9l29GL68L7
    # fazH54XJyRr+M2dINjLIBcgJl6XCzWWbJlrbHJiS2tUUZ0iWVHEQDf2GtY8ues/Y
    # mQmXInFrbYjdk3mIS8ARpI5e1A7Iia1G+0QYV49BAEa82rWTBYYSJz0Ri7c80cbT
    # 6EcAY2vJI0zkwvld5lMzQTBWQTHWavpbNFsg0nkTcQDHz9PhBn1mZPQuQ3E9GQol
    # F2V2Kt3qs3ktcM5NE5mPxx/71dJ1ZjyxMLH9iaphve/rc8ur5he7mJRfSfJ5zz1B
    # xLc1TTTeLU36Zxj0wuPeLlKPDTO+cBQv5I3mYpHjP8we9HO8ZmKJKmUf2JAQ32Ex
    # iA+VxgV9wqGCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzUyWjAjBgkqhkiG9w0BCQQx
    # FgQU8LLUUHg7HD4Y2deBiNd0xE5FBSswDQYJKoZIhvcNAQEBBQAEggEAZ7qXOtGY
    # AD+Gaz25YxHDh3l0/bwTfBsDG7JtcRsXwOtojOcMagu+zQkQvVBcwV0Rgu7iNiSs
    # C3SsESJ5O5vl5l5Y64sCufnvFXVGNrovopc+drz+3FEACOJBBaB4DHWv0LpK87qN
    # DXpnhgEH0Ts6K6E0upVACxYv+UZaocoCkFHZkYz+Flws5mc6XWoeVVC2n9rOukro
    # +LmwC7ttjz3w/JJUp8I2oGrhdkUIF6y++y41U1P+sB9xF12lojrZAI9YAEY0oVcy
    # 6LUq1rLsVAWa0CsTs2pFXDpWSldcR74BzqE37kw+BhE4awRYDuP0srPVBgJHWuHi
    # ENtIpRDoqyeHqA==
    # SIG # End signature block
    
  • tools\Functions\Assertions\BeTrueOrFalse.ps1 Show
    function Should-BeTrue($ActualValue, [switch] $Negate, [string] $Because) {
        <#
    .SYNOPSIS
    Asserts that the value is true, or truthy.
    
    .EXAMPLE
    $true | Should -BeTrue
    This test passes. $true is true.
    
    .EXAMPLE
    1 | Should -BeTrue
    This test passes. 1 is true.
    
    .EXAMPLE
    1,2,3 | Should -BeTrue
    PowerShell does not enter a `If (-not @(1,2,3)) {}` block.
    This test passes as a "truthy" result.
    #>
        if ($Negate) {
            return Should-BeFalse -ActualValue $ActualValue -Negate:$false -Because $Because
        }
    
        if (-not $ActualValue) {
            $failureMessage = "Expected `$true,$(Format-Because $Because) but got $(Format-Nicely $ActualValue)."
            return New-Object psobject -Property @{
                Succeeded      = $false
                FailureMessage = $failureMessage
            }
        }
    
        return New-Object psobject -Property @{
            Succeeded = $true
        }
    }
    
    function Should-BeFalse($ActualValue, [switch] $Negate, $Because) {
        <#
    .SYNOPSIS
    Asserts that the value is false, or falsy.
    
    .EXAMPLE
    $false | Should -BeFalse
    This test passes. $false is false.
    
    .EXAMPLE
    0 | Should -BeFalse
    This test passes. 0 is false.
    
    .EXAMPLE
    $null | Should -BeFalse
    PowerShell does not enter a `If ($null) {}` block.
    This test passes as a "falsy" result.
    #>
        if ($Negate) {
            return Should-BeTrue -ActualValue $ActualValue -Negate:$false -Because $Because
        }
    
        if ($ActualValue) {
            $failureMessage = "Expected `$false,$(Format-Because $Because) but got $(Format-Nicely $ActualValue)."
            return New-Object psobject -Property @{
                Succeeded      = $false
                FailureMessage = $failureMessage
            }
        }
    
        return New-Object psobject -Property @{
            Succeeded = $true
        }
    }
    
    
    Add-AssertionOperator -Name         BeTrue `
        -InternalName Should-BeTrue `
        -Test         ${function:Should-BeTrue}
    
    Add-AssertionOperator -Name         BeFalse `
        -InternalName Should-BeFalse `
        -Test         ${function:Should-BeFalse}
    
    
    
    # to keep tests happy
    function ShouldBeTrueFailureMessage($ActualValue) {
    }
    function NotShouldBeTrueFailureMessage($ActualValue) {
    }
    function ShouldBeFalseFailureMessage($ActualValue) {
    }
    function NotShouldBeFalseFailureMessage($ActualValue) {
    }
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUIkpJE6BOt9y5hyOSL1GLatdt
    # 3YiggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # v2tUlgOwhox0AQPu8o42lGzoL9kwDQYJKoZIhvcNAQEBBQAEggEAF88TMdCQsefo
    # 4TWPeemKG0VPtnSiUCwOZwb2q/uY/DHvCPFnm8XB/vb1HWe52rql1bYaGno5OX7F
    # STSoyQec0le77B7L3KkXzCRlgAwW+WX8nO/1O0n2xR458zhhEy0iz63qtFbdHwsI
    # UylecQSuv6/P+fB+L0EeaC75DfDJbWmCk/Rr7BmdHCzKQZznsbYUWQxqemjgRrNz
    # EX70pW5yevFzHbfz6jzjdAmcHzHDQcpfrvCny4+6YyL5CbSv5h7CkPXebOUbVB5j
    # o4wrlMgbL7QFmHN8oBY//JIzBAWMONdoJm0hX8y8qzlBzKuf8hkQDHRHTb1/QCZn
    # g3/DA8JmBqGCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzUzWjAjBgkqhkiG9w0BCQQx
    # FgQUb9A294DObwSARkD6cu3pBVrgUJ4wDQYJKoZIhvcNAQEBBQAEggEAWPUy1uZJ
    # RwrZ+nO0n0HNZlEuQ+bUFNVohh5+GecODNmW8YT55sM/Vf7fSpQFGmyK5QXKIYrk
    # nLE3T6dkkbOhEy5VJDHAnu4X30ehYa+EFukkyui+MFD7oofwiziXF7hVmOHnytQ0
    # qMdFrZfRZrLe2AlJ7R8JJkhe5JYBeSR07doDLR3HO6IsrCwqQYpESjVji7EfO/Gd
    # HFEDts500iHaePvQyMUqljVryJZP4VWmoc5Hr+/GrvRyDdBK2JLcq1Ybhz5zo8Hn
    # iLgLWyJsjwmoKh+ITDi2wOXBKPNCP56B0DahWkCWT6MzfBMNSjRHxgo/vqN2NuOd
    # awp8UDsqOAkH6A==
    # SIG # End signature block
    
  • tools\Functions\Assertions\Contain.ps1 Show
    function Should-Contain($ActualValue, $ExpectedValue, [switch] $Negate, [string] $Because) {
        <#
    .SYNOPSIS
    Asserts that collection contains a specific value.
    Uses PowerShell's -contains operator to confirm.
    
    .EXAMPLE
    1,2,3 | Should -Contain 1
    This test passes, as 1 exists in the provided collection.
    #>
        [bool] $succeeded = $ActualValue -contains $ExpectedValue
        if ($Negate) {
            $succeeded = -not $succeeded
        }
    
        if (-not $succeeded) {
            if ($Negate) {
                return New-Object psobject -Property @{
                    Succeeded      = $false
                    FailureMessage = "Expected $(Format-Nicely $ExpectedValue) to not be found in collection $(Format-Nicely $ActualValue),$(Format-Because $Because) but it was found."
                }
            }
            else {
                return New-Object psobject -Property @{
                    Succeeded      = $false
                    FailureMessage = "Expected $(Format-Nicely $ExpectedValue) to be found in collection $(Format-Nicely $ActualValue),$(Format-Because $Because) but it was not found."
                }
            }
        }
    
        return New-Object psobject -Property @{
            Succeeded = $true
        }
    }
    
    Add-AssertionOperator -Name         Contain `
        -InternalName Should-Contain `
        -Test         ${function:Should-Contain} `
        -SupportsArrayInput
    
    function ShouldContainFailureMessage() {
    }
    function NotShouldContainFailureMessage() {
    }
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUATXrSkUOxkTBKAsj/xC2G25W
    # +nSggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # kK80QJoz3HoiPh8NSTzFm+Bggk8wDQYJKoZIhvcNAQEBBQAEggEAI3Kdqf/aoPRc
    # 47QPP8HorNViLKPpFZZZhA1fQytr06WPu1OfjyFJ/FkXHvphUQj/TtIdsZh3RLhd
    # u2Exp136gpl1yCqRO8xe8jYx33ZiLRmOeMGlE6+UlHHmgjKEGDsoKxrMumczxN8T
    # ZDJWcKkUOdnfeKpZUmaxvn1y7eCivNv79V5VAo6V/urbEKRkyj2Jwa26EKHRY1DN
    # jGtwo6APRW3BiYU2ua6l+3/JNdgMuw6LkK51lXiTGNGS5oSguxSC74s+Thc5b0pR
    # 9QxD52vF9TlmNdVE1Z4TvqRmfRMm1UtZKCea3cnKsh2s2wlZ4LPMdkDvEf5eyKiR
    # OscAyavlxKGCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzUzWjAjBgkqhkiG9w0BCQQx
    # FgQUWlbwINycWahkdbb56QUdGhofi0EwDQYJKoZIhvcNAQEBBQAEggEAGzCRVUCQ
    # KKiw0w5WGQHjbs13BEc5Kk96rWbBIE9N+qLNQxhUevSH/k7D+dbvXJDQ3cZq6id3
    # uleGErzLGCR0oFVgnVxQYuyYv63Z4QtIipN/SltsG3TrgObjQ1t49p3GOg5xIyKf
    # r+yfGcjNbqsOotQ/tJPNYjlbNVBW/012KNPWbstCX9AYpiXS+E3CkVU9+N+RxwMx
    # hXJKwjioLW9jSpznVMc8HMEgZiVX2yOmJQwYZMErO5ymSmi5wFk9KQUoKNM+jlGO
    # 7rlpXffqnE7ThKsdJFZDIup2ub+duXe6Yun1TC6YAP6Qx5oX/6Zz0PFYa6uDhN++
    # lk7SLmuu54cS7g==
    # SIG # End signature block
    
  • tools\Functions\Assertions\Exist.ps1 Show
    function Should-Exist($ActualValue, [switch] $Negate, [string] $Because) {
        <#
    .SYNOPSIS
    Does not perform any comparison, but checks if the object calling Exist is present in a PS Provider.
    The object must have valid path syntax. It essentially must pass a Test-Path call.
    
    .EXAMPLE
    $actual = (Dir . )[0].FullName
    PS C:\>Remove-Item $actual
    PS C:\>$actual | Should -Exist
    
    `Should -Exist` calls Test-Path. Test-Path expects a file,
    returns $false because the file was removed, and fails the test.
    #>
        [bool] $succeeded = & $SafeCommands['Test-Path'] $ActualValue
    
        if ($Negate) {
            $succeeded = -not $succeeded
        }
    
        $failureMessage = ''
    
        if (-not $succeeded) {
            if ($Negate) {
                $failureMessage = "Expected path $(Format-Nicely $ActualValue) to not exist,$(Format-Because $Because) but it did exist."
            }
            else {
                $failureMessage = "Expected path $(Format-Nicely $ActualValue) to exist,$(Format-Because $Because) but it did not exist."
            }
        }
    
        return & $SafeCommands['New-Object'] psobject -Property @{
            Succeeded      = $succeeded
            FailureMessage = $failureMessage
        }
    }
    
    Add-AssertionOperator -Name         Exist `
        -InternalName Should-Exist `
        -Test         ${function:Should-Exist}
    
    
    function ShouldExistFailureMessage() {
    }
    function NotShouldExistFailureMessage() {
    }
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUFHNJxYlCaLJvJlGn8mdQgQP+
    # z2iggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # ggA/7v2jOm4gOYPJGCuk9mkaOLcwDQYJKoZIhvcNAQEBBQAEggEAppxI7DNdnoph
    # XNrfBlU7y4+fAFy8IGJhs+dmw6vlxT6Bx5o1ScXMBhRfS03WH4sXGLCdBJm2NNfq
    # xap/vRUzBHrJtOZup78xa+Ot2zUK+3nNCXOKGfyt1pjBKK0prn8N4Xc15vv3xJwv
    # 3crRcotkgdoppPWZ6B4cDYn1ou8VKvQP24DLgr4XMvR6JCXTwIYnk/61dp1wsUvA
    # F/MeDQ5+/EuvzXJL5XuLOpDhkfdHp/dO95Wv1qTOfqw3v1tZNGqs7f6wGyMjkHMZ
    # tA9s3A2cs7UdRBlECZ2Hs2RJ5gsv+Rl99gzOlC2RJHzfqGx2p7HEIluJy4YMq27h
    # V8pxoz+lq6GCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzU0WjAjBgkqhkiG9w0BCQQx
    # FgQUDyqd9NXSY+7oVt1UOn1h18X29M0wDQYJKoZIhvcNAQEBBQAEggEAi9LxbnIN
    # lmiH50sm1ANyRia5FL0gS4i3plAzUMicZBloasXi23Y+ljTLOCrn/8Y29ck7FLz4
    # wWxW23YaagV1vwGgiV8IhlFLow9E1i8+YPzlRUMexM4hnGt102l2Dcfayj/yj1eK
    # T7NOMOAbybCv4wryxdEzBSGIv0RodY3R3pJQSXRVUMiDqbD0zd3yymCa2IFcsjlR
    # +CC8XHTztJyD+gYETUtPfxoaaa4KlA0E1ckTxwUdolG+jula3lbfqgY1S9+ukL8O
    # HxNn4b7jGmmQH9KNknBvV41WSvlvj+DaQfXjGqDxtBvyAOXbzjhU9kTH8q+cy1s7
    # Uc/jI3wy8zRPsQ==
    # SIG # End signature block
    
  • tools\Functions\Assertions\FileContentMatch.ps1 Show
    function Should-FileContentMatch($ActualValue, $ExpectedContent, [switch] $Negate, $Because) {
        <#
    .SYNOPSIS
    Checks to see if a file contains the specified text.
    This search is not case sensitive and uses regular expressions.
    
    .EXAMPLE
    Set-Content -Path TestDrive:\file.txt -Value 'I am a file.'
    PS C:\>'TestDrive:\file.txt' | Should -FileContentMatch 'I Am'
    
    Create a new file and verify its content. This test passes.
    The 'I Am' regular expression (RegEx) pattern matches against the txt file contents.
    For case-sensitivity, see FileContentMatchExactly.
    
    .EXAMPLE
    'TestDrive:\file.txt' | Should -FileContentMatch '^I.*file\.$'
    This RegEx pattern also matches against the "I am a file." string from Example 1.
    With a matching RegEx pattern, this test also passes.
    
    .EXAMPLE
    'TestDrive:\file.txt' | Should -FileContentMatch 'I Am Not'
    This test fails, as the RegEx pattern does not match "I am a file."
    
    .EXAMPLE
    'TestDrive:\file.txt' | Should -FileContentMatch 'I.am.a.file'
    This test passes, because "." in RegEx matches any character including a space.
    
    .EXAMPLE
    'TestDrive:\file.txt' | Should -FileContentMatch ([regex]::Escape('I.am.a.file'))
    Tip: Use [regex]::Escape("pattern") to match the exact text.
    This test fails, because "I am a file." != "I.am.a.file"
    #>
        $succeeded = (@(& $SafeCommands['Get-Content'] -Encoding UTF8 $ActualValue) -match $ExpectedContent).Count -gt 0
    
        if ($Negate) {
            $succeeded = -not $succeeded
        }
    
        $failureMessage = ''
    
        if (-not $succeeded) {
            if ($Negate) {
                $failureMessage = NotShouldFileContentMatchFailureMessage -ActualValue $ActualValue -ExpectedContent $ExpectedContent -Because $Because
            }
            else {
                $failureMessage = ShouldFileContentMatchFailureMessage -ActualValue $ActualValue -ExpectedContent $ExpectedContent -Because $Because
            }
        }
    
        return & $SafeCommands['New-Object'] psobject -Property @{
            Succeeded      = $succeeded
            FailureMessage = $failureMessage
        }
    }
    
    function ShouldFileContentMatchFailureMessage($ActualValue, $ExpectedContent, $Because) {
        return "Expected $(Format-Nicely $ExpectedContent) to be found in file '$ActualValue',$(Format-Because $Because) but it was not found."
    }
    
    function NotShouldFileContentMatchFailureMessage($ActualValue, $ExpectedContent, $Because) {
        return "Expected $(Format-Nicely $ExpectedContent) to not be found in file '$ActualValue',$(Format-Because $Because) but it was found."
    }
    
    Add-AssertionOperator -Name         FileContentMatch `
        -InternalName Should-FileContentMatch `
        -Test         ${function:Should-FileContentMatch}
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQU4WIISJhmilLw7Pb4gqNq724z
    # etmggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # L3sHaAdAjZmnh5VY11kK3/76uicwDQYJKoZIhvcNAQEBBQAEggEASHmNvFJvsRqb
    # V/B2ccWqSaO+KL37iakrdHjLX/UNHM+IEjGEddYlC6VdFlM795j3OC3kx9yuGPd/
    # Plj2D8Z9FsPujoEWB1PkX7Q59WbOewPfHYkClz5MTwZ09tcMTLfYeohthWemFzoB
    # XjK1nuY0PdIbzdnC7C2VvJGsjtz0HIrbCFD4LybVcrp03s95YZsnK2INvrC0PsMx
    # dmNXR0kR3nrCyb8tRBTESti38Hr9609O/w6N1q8kg73exgak5vRTWqH/MKb51ujp
    # ei0a0wYBYRyGi88tUjgPafs2FSNSLgbjoGVrVGUtYR1vPYhFu1d3c8IJWdcFnaVo
    # kuRjwFRtLaGCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzU0WjAjBgkqhkiG9w0BCQQx
    # FgQU8+PjQBuvbVvegImZ4MyTop036qswDQYJKoZIhvcNAQEBBQAEggEAVMcRSDpD
    # KkatCH/gCNYFhhBLBFi03qMtAxmjwiTlBIs9qSWnL0PA31Q0+94VoHXwGcK0WLSW
    # zF9/UuvLs59fuGb4yniAEX90cNB5yIM5Ejw1T35eAk3T+pJX4QbFj/YMAHYJCg4+
    # 9IscFqpLLWbo9zOKy8V60dUKO/dwdUoT9zdti6xgIq/2/4MjHJmMsC7qnBGLDZC+
    # Rvung7ERiQ40NpcQg7ww/U9x5AcXn2AdzqdBy7uEr+PYTWmp0uH3UMx3tclLftMi
    # 7lnAqXNBeHLeOXYL3BSm5znhUtGC8EqqELgIEEl2a4Rw7lasIA4CvCp+Mfq0QQ+1
    # DgISusgA7HIBJw==
    # SIG # End signature block
    
  • tools\Functions\Assertions\FileContentMatchExactly.ps1 Show
    function Should-FileContentMatchExactly($ActualValue, $ExpectedContent, [switch] $Negate, [String] $Because) {
        <#
    .SYNOPSIS
    Checks to see if a file contains the specified text.
    This search is case sensitive and uses regular expressions to match the text.
    
    .EXAMPLE
    Set-Content -Path TestDrive:\file.txt -Value 'I am a file.'
    PS C:\>'TestDrive:\file.txt' | Should -FileContentMatchExactly 'I am'
    
    Create a new file and verify its content. This test passes.
    The 'I am' regular expression (RegEx) pattern matches against the txt file contents.
    
    .EXAMPLE
    'TestDrive:\file.txt' | Should -FileContentMatchExactly 'I Am'
    This test checks a case-sensitive pattern against the "I am a file." string from Example 1.
    Because the RegEx pattern fails to match, this test fails.
    #>
        $succeeded = (@(& $SafeCommands['Get-Content'] -Encoding UTF8 $ActualValue) -cmatch $ExpectedContent).Count -gt 0
    
        if ($Negate) {
            $succeeded = -not $succeeded
        }
    
        $failureMessage = ''
    
        if (-not $succeeded) {
            if ($Negate) {
                $failureMessage = NotShouldFileContentMatchExactlyFailureMessage -ActualValue $ActualValue -ExpectedContent $ExpectedContent -Because $Because
            }
            else {
                $failureMessage = ShouldFileContentMatchExactlyFailureMessage -ActualValue $ActualValue -ExpectedContent $ExpectedContent -Because $Because
            }
        }
    
        return & $SafeCommands['New-Object'] psobject -Property @{
            Succeeded      = $succeeded
            FailureMessage = $failureMessage
        }
    }
    
    function ShouldFileContentMatchExactlyFailureMessage($ActualValue, $ExpectedContent) {
        return "Expected $(Format-Nicely $ExpectedContent) to be case sensitively found in file $(Format-Nicely $ActualValue),$(Format-Because $Because) but it was not found."
    }
    
    function NotShouldFileContentMatchExactlyFailureMessage($ActualValue, $ExpectedContent) {
        return "Expected $(Format-Nicely $ExpectedContent) to not be case sensitively found in file $(Format-Nicely $ActualValue),$(Format-Because $Because) but it was found."
    }
    
    Add-AssertionOperator -Name         FileContentMatchExactly `
        -InternalName Should-FileContentMatchExactly `
        -Test         ${function:Should-FileContentMatchExactly}
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUls7jxCA+j4XmhTiCgSiu6Cv0
    # jKeggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # gfNbQmqWA7KEUu/deD0xGBqY4yIwDQYJKoZIhvcNAQEBBQAEggEACgJX5Q+twdJ1
    # Vef1XZCULvW/nsNeeHO4btJmpQADjRtv57wQU9FkfQsQ3Vx1j0HygTyXfqvbbviU
    # tNCiD6+UXrcO1DiUxUhBLpSoo1u3FO61CNBpmkXpyfvfErBVXiShPfBxd7m7ENk5
    # ibI/ne1kiodztH1JbPNOnXigu19mTle4vLQYzFLvVasN7bBFmKcuYQj8fQryCOA3
    # PsNCGROEIETrosKdrMuQd68DX4QgmsRLqp9quRNmOabDa4qP4WWlgJoXkqM39HJX
    # BEuOyxNf4sFzU6PrRquOmnDQxC4qQB9Yy5yzx7F0N4ry9WzIWSDPL3r1AFOx6r7B
    # QblFQyzxpKGCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzU1WjAjBgkqhkiG9w0BCQQx
    # FgQUj2OAyQOsoj9xefIP8680tikelhMwDQYJKoZIhvcNAQEBBQAEggEAdW4eoE/e
    # PrOamXTtO9wfUDXALl2q2gJbkdqhGIk+PAAoNbTfhveo8dyJ+OKa/CA0+xVck+9M
    # qU+0f3UETFWKhQw43HbZ/UGSDmD6wHXkyW2QABENahQtfCvCdmvxkpkGasM16mTq
    # g7IewM6ObZNafoesusXrwTW7FCyNm32XYrsE+hnw+5ni56VBdUoWymggH+mdgm3o
    # ysUImUeCdnSj0C5wHzK4/kp6KW0IXC9+9XpSQyqItbKrxs3FKiod3OhcYol3G/gX
    # uiqEUv/OnSmdTJk7oCUIPYdUoKc8LVZAWokeG975Idg3asNeHNE/k+LXVN09hIk0
    # Ux19d8rXMLSKvw==
    # SIG # End signature block
    
  • tools\Functions\Assertions\FileContentMatchMultiline.ps1 Show
    function Should-FileContentMatchMultiline($ActualValue, $ExpectedContent, [switch] $Negate, [String] $Because) {
        <#
    .SYNOPSIS
    As opposed to FileContentMatch and FileContentMatchExactly operators,
    FileContentMatchMultiline presents content of the file being tested as one string object,
    so that the expression you are comparing it to can consist of several lines.
    
    When using FileContentMatchMultiline operator, '^' and '$' represent the beginning and end
    of the whole file, instead of the beginning and end of a line.
    
    .EXAMPLE
    $Content = "I am the first line.`nI am the second line."
    PS C:\>Set-Content -Path TestDrive:\file.txt -Value $Content -NoNewline
    PS C:\>'TestDrive:\file.txt' | Should -FileContentMatchMultiline 'first line\.\r?\nI am'
    
    This regular expression (RegEx) pattern matches the file contents, and the test passes.
    
    .EXAMPLE
    'TestDrive:\file.txt' | Should -FileContentMatchMultiline '^I am the first.*\n.*second line\.$'
    Using the file from Example 1, this RegEx pattern also matches, and this test also passes.
    
    .EXAMPLE
    'TestDrive:\file.txt' | Should -FileContentMatchMultiline '^I am the first line\.$'
    FileContentMatchMultiline uses the '$' symbol to match the end of the file,
    not the end of any single line within the file. This test fails.
    #>
        $succeeded = [bool] ((& $SafeCommands['Get-Content'] $ActualValue -Delimiter ([char]0)) -match $ExpectedContent)
    
        if ($Negate) {
            $succeeded = -not $succeeded
        }
    
        $failureMessage = ''
    
        if (-not $succeeded) {
            if ($Negate) {
                $failureMessage = NotShouldFileContentMatchMultilineFailureMessage -ActualValue $ActualValue -ExpectedContent $ExpectedContent -Because $Because
            }
            else {
                $failureMessage = ShouldFileContentMatchMultilineFailureMessage -ActualValue $ActualValue -ExpectedContent $ExpectedContent -Because $Because
            }
        }
    
        return New-Object psobject -Property @{
            Succeeded      = $succeeded
            FailureMessage = $failureMessage
        }
    }
    
    function ShouldFileContentMatchMultilineFailureMessage($ActualValue, $ExpectedContent, $Because) {
        return "Expected $(Format-Nicely $ExpectedContent) to be found in file $(Format-Nicely $ActualValue),$(Format-Because $Because) but it was not found."
    }
    
    function NotShouldFileContentMatchMultilineFailureMessage($ActualValue, $ExpectedContent, $Because) {
        return "Expected $(Format-Nicely $ExpectedContent) to not be found in file $(Format-Nicely $ActualValue),$(Format-Because $Because) but it was found."
    }
    
    Add-AssertionOperator -Name         FileContentMatchMultiline `
        -InternalName Should-FileContentMatchMultiline `
        -Test         ${function:Should-FileContentMatchMultiline}
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQU3Gq8DK0AsXrptfqIsMI/X6bi
    # dVqggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # tNg19qbN4Kmbc4zhjZcId0s0fMcwDQYJKoZIhvcNAQEBBQAEggEAgD2GfrFhXUoi
    # zDVjoTRQM9R2dPsX51Fx327rbXXGRm0NS+l49/J91GyAglzSo1w+WulsuIXA47i5
    # /XpuSBePb8e2b9xtgP17SVFVfL+6WbnJy5TfzJ76NlAZuSnyaltG34YM0E4PojmR
    # v4oZfZdrtpsWXaUy2zW9XHp/Hr6CwVQuh5wQ1rSgAsEpUJmR73498vm1aP0+yb0/
    # 8UMIU/j1L0csR7vU4ohJuOOPcR8tuow9vOu8dDQbEt9I4Akvx2p6BFSLeUNDVZJJ
    # 9C9CZ2HnUuFrPP0BGbsaxMzlZLwBPk4mh+RFaKgqZnWw7fAy8FDUnSDret52vosL
    # yL8o5Kf9+qGCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzU2WjAjBgkqhkiG9w0BCQQx
    # FgQUz8Bt17IY0+UKCXMAFn9sAahWVZ0wDQYJKoZIhvcNAQEBBQAEggEAjESsY8P1
    # /Wa5Bijb40XgabDhBcRunleyLVFIdgOyQp/SW06to9HywhGtCWYEQPlaeP+7rBTh
    # thNjAzl3AoNw4wQmS8kFDsaFK/j7W/PozF4JeWqnCqv71JLzfwwx+mnqUz9mlr8X
    # llZAe/H+LwGA05ySXzbv4vXzq/p9bM/ozejvOSxrl3zC2jchJD7a0x9gV+NQHU00
    # BtpM7hj/6ZjJRdWcgRBAPawErPiq2qSPG47n3loKKfBY4eSLP4BtBlrNnUugq/PW
    # R0spQXU8rn1legCD04LN5G6Oj+JGKl5JG2BJKxexRUCkKWPGgfCeMHi9jlNsV/N4
    # ot7xIjlQ4U+Jeg==
    # SIG # End signature block
    
  • tools\Functions\Assertions\HaveCount.ps1 Show
    function Should-HaveCount($ActualValue, [int] $ExpectedValue, [switch] $Negate, [string] $Because) {
        <#
    .SYNOPSIS
    Asserts that a collection has the expected amount of items.
    
    .EXAMPLE
    1,2,3 | Should -HaveCount 3
    This test passes, because it expected three objects, and received three.
    This is like running `@(1,2,3).Count` in PowerShell.
    #>
        if ($ExpectedValue -lt 0) {
            throw [ArgumentException]"Excpected collection size must be greater than or equal to 0."
        }
        $count = if ($null -eq $ActualValue) {
            0
        }
        else {
            $ActualValue.Count
        }
        $expectingEmpty = $ExpectedValue -eq 0
        [bool] $succeeded = $count -eq $ExpectedValue
        if ($Negate) {
            $succeeded = -not $succeeded
        }
    
    
        if (-not $succeeded) {
    
            if ($Negate) {
                $expect = if ($expectingEmpty) {
                    "Expected a non-empty collection"
                }
                else {
                    "Expected a collection with size different from $(Format-Nicely $ExpectedValue)"
                }
                $but = if ($count -ne 0) {
                    "but got collection with that size $(Format-Nicely $ActualValue)."
                }
                else {
                    "but got an empty collection."
                }
                return New-Object psobject -Property @{
                    Succeeded      = $false
                    FailureMessage = "$expect,$(Format-Because $Because) $but"
                }
            }
            else {
                $expect = if ($expectingEmpty) {
                    "Expected an empty collection"
                }
                else {
                    "Expected a collection with size $(Format-Nicely $ExpectedValue)"
                }
                $but = if ($count -ne 0) {
                    "but got collection with size $(Format-Nicely $count) $(Format-Nicely $ActualValue)."
                }
                else {
                    "but got an empty collection."
                }
                return New-Object psobject -Property @{
                    Succeeded      = $false
                    FailureMessage = "$expect,$(Format-Because $Because) $but"
                }
            }
        }
    
        return New-Object psobject -Property @{
            Succeeded = $true
        }
    }
    
    Add-AssertionOperator -Name         HaveCount `
        -InternalName Should-HaveCount `
        -Test         ${function:Should-HaveCount} `
        -SupportsArrayInput
    
    function ShouldHaveCountFailureMessage() {
    }
    function NotShouldHaveCountFailureMessage() {
    }
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUA9FZoIr/Qis+B3Uv7asGdjXX
    # J9aggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # 40xTtfW6P1Knx1ioz2f5DVczi1AwDQYJKoZIhvcNAQEBBQAEggEAf1ZPEbyfvUzR
    # IDFPwAkyNwInCEXKY8tSObijz93nmznYLAlDgHGp2iyToVU+Sgrwru5nRoVYIv/C
    # GfkEy3swfa2lmJmQDtiw1s5fr+vZltPyjcbAkpa4eFgk6OKmjeGrr0Qb+LwdpKeC
    # 4C0WeKh48t1JBOy+9HucWu76oP8jYV8q4KPT8dpCzFx9jvC9BD7xQwiBpCy9EbP5
    # SGiIW8XWE/2FCogWcAySClplENSsXPfLAVVqfBFvE1TvqSSO8CW7hj+TkdrDQZ2t
    # ivXbparBe/kjASq7j4GfheUkKRfp/xZhfgO3PfrT+Ker/gSmnYZB3ofmbQKPUZl1
    # LgKeJ4DwuqGCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzU2WjAjBgkqhkiG9w0BCQQx
    # FgQU8pKALASpp7+SL/aN54Pw168MzecwDQYJKoZIhvcNAQEBBQAEggEAoGXbLQPg
    # MoJ/quc2UiFv83lKm9up7Yr1eas3pXTjaOb+Ix2b+v5LWT54dQwnEHt9MHaR+hJg
    # 6KmBugbqyZpEijpIYbTUroMErRTYBV0Pwyvp4LKcQ/xl8351fCqyoE5B33jlsmon
    # gJBnfkDTH/ERYvhIzu0sp2KEHKnfzCCGfc1JttcAsaPACIXnJhrDCStxiQKdKpqm
    # jHKO0KTPVDVzV70tLtO19GrOuoWEO83kTrL+Yh6TUC9Dj/MPeDSUp7z9NoGMTs0J
    # sP84CQvv1NCJQFay9Qr4c2KpDcrHy6k998XgMolaWgxhJ2eSUXqyw/fJNRPlFuUy
    # NFXGPcJPXDdSxQ==
    # SIG # End signature block
    
  • tools\Functions\Assertions\HaveParameter.ps1 Show
    function Should-HaveParameter (
        $ActualValue,
        [String] $ParameterName,
        $Type,
        [String]$DefaultValue,
        [Switch]$Mandatory,
        [Switch]$HasArgumentCompleter,
        [Switch]$Negate,
        [String]$Because ) {
        <#
        .SYNOPSIS
            Asserts that a command has the expected parameter.
    
        .EXAMPLE
            Get-Command "Invoke-WebRequest" | Should -HaveParameter Uri -Mandatory
            This test passes, because it expected the parameter URI to exist and to
            be mandatory.
        .NOTES
            The attribute [ArgumentCompleter] was added with PSv5. Previouse this
            assertion will not be able to use the -HasArgumentCompleter parameter
            if the attribute does not exist.
        #>
    
        if ($null -eq $ActualValue -or $ActualValue -isnot [Management.Automation.CommandInfo]) {
            throw "Input value must be non-null CommandInfo object. You can get one by calling Get-Command."
        }
    
        if ($null -eq $ParameterName) {
            throw "The ParameterName can't be empty"
        }
    
        #region HelperFunctions
        function Join-And ($Items, $Threshold = 2) {
    
            if ($null -eq $items -or $items.count -lt $Threshold) {
                $items -join ', '
            }
            else {
                $c = $items.count
                ($items[0..($c - 2)] -join ', ') + ' and ' + $items[-1]
            }
        }
    
        function Add-SpaceToNonEmptyString ([string]$Value) {
            if ($Value) {
                " $Value"
            }
        }
    
        function Get-ParameterInfo {
            param(
                [Parameter( Mandatory = $true )]
                [Management.Automation.CommandInfo]$Command
            )
            <#
            .SYNOPSIS
                Use Tokenize to get information about the parameter block of a command
            .DESCRIPTION
                In order to get information about the parameter block of a command,
                several tools can be used (Get-Command, AST, etc).
                In order to get the default value of a parameter, AST is the easiest
                way to go; but AST was only introduced with PSv3.
                This function creates an object with information about parameters
                using the Tokenize
            .NOTES
                Author: Chris Dent
            #>
    
            function Get-TokenGroup {
                param(
                    [Parameter( Mandatory = $true )]
                    [System.Management.Automation.PSToken[]]$tokens
                )
                $i = $j = 0
                do {
                    $token = $tokens[$i]
                    if ($token.Type -eq 'GroupStart') {
                        $j++
                    }
                    if ($token.Type -eq 'GroupEnd') {
                        $j--
                    }
                    if (-not $token.PSObject.Properties.Item('Depth')) {
                        $token | Add-Member Depth -MemberType NoteProperty -Value $j
                    }
                    $token
    
                    $i++
                } until ($j -eq 0 -or $i -ge $tokens.Count)
            }
    
            $errors = $null
            $tokens = [System.Management.Automation.PSParser]::Tokenize($Command.Definition, [Ref]$errors)
    
            # Find param block
            $start = $tokens.IndexOf(($tokens | Where-Object { $_.Content -eq 'param' } | Select-Object -First 1)) + 1
            $paramBlock = Get-TokenGroup $tokens[$start..($tokens.Count - 1)]
    
            for ($i = 0; $i -lt $paramBlock.Count; $i++) {
                $token = $paramBlock[$i]
    
                if ($token.Depth -eq 1 -and $token.Type -eq 'Variable') {
                    $paramInfo = New-Object PSObject -Property @{
                        Name = $token.Content
                    } | Select-Object Name, Type, DefaultValue, DefaultValueType
    
                    if ($paramBlock[$i + 1].Content -ne ',') {
                        $value = $paramBlock[$i + 2]
                        if ($value.Type -eq 'GroupStart') {
                            $tokenGroup = Get-TokenGroup $paramBlock[($i + 2)..($paramBlock.Count - 1)]
                            $paramInfo.DefaultValue = [String]::Join('', ($tokenGroup | ForEach-Object { $_.Content }))
                            $paramInfo.DefaultValueType = 'Expression'
                        }
                        else {
                            $paramInfo.DefaultValue = $value.Content
                            $paramInfo.DefaultValueType = $value.Type
                        }
                    }
                    if ($paramBlock[$i - 1].Type -eq 'Type') {
                        $paramInfo.Type = $paramBlock[$i - 1].Content
                    }
                    $paramInfo
                }
            }
        }
    
        if ($Type -is [string]) {
            # parses type that is provided as a string in brackets (such as [int])
            $parsedType = ($Type -replace '^\[(.*)\]$', '$1') -as [Type]
            if ($null -eq $parsedType) {
                throw [ArgumentException]"Could not find type [$ParsedType]. Make sure that the assembly that contains that type is loaded."
            }
    
            $Type = $parsedType
        }
        #endregion HelperFunctions
    
        $buts = @()
        $filters = @()
    
        $null = $ActualValue.Parameters # necessary for PSv2
        $hasKey = $ActualValue.Parameters.PSBase.ContainsKey($ParameterName)
        $filters += "to$(if ($Negate) {" not"}) have a parameter $ParameterName"
    
        if (-not $Negate -and -not $hasKey) {
            $buts += "the parameter is missing"
        }
        elseif ($Negate -and -not $hasKey) {
            return New-Object PSObject -Property @{ Succeeded = $true }
        }
        elseif ($Negate -and $hasKey -and -not ($Mandatory -or $Type -or $DefaultValue -or $HasArgumentCompleter)) {
            $buts += "the parameter exists"
        }
        else {
            $attributes = $ActualValue.Parameters[$ParameterName].Attributes
    
            if ($Mandatory) {
                $testMandatory = $attributes | Where-Object { $_ -is [System.Management.Automation.ParameterAttribute] -and $_.Mandatory }
                $filters += "which is$(if ($Negate) {" not"}) mandatory"
    
                if (-not $Negate -and -not $testMandatory) {
                    $buts += "it wasn't mandatory"
                }
                elseif ($Negate -and $testMandatory) {
                    $buts += "it was mandatory"
                }
            }
    
            if ($Type) {
                # This block is not using `Format-Nicely`, as in PSv2 the output differs. Eg:
                # PS2> [System.DateTime]
                # PS5> [datetime]
                [type]$actualType = $ActualValue.Parameters[$ParameterName].ParameterType
                $testType = ($Type -eq $actualType)
                $filters += "$(if ($Negate) {"not "})of type [$($Type.FullName)]"
    
                if (-not $Negate -and -not $testType) {
                    $buts += "it was of type [$($actualType.FullName)]"
                }
                elseif ($Negate -and $testType) {
                    $buts += "it was of type [$($Type.FullName)]"
                }
            }
    
            if ($PSBoundParameters.Keys -contains "DefaultValue") {
                $parameterMetadata = Get-ParameterInfo $ActualValue | Where-Object { $_.Name -eq $ParameterName }
                $actualDefault = if ($parameterMetadata.DefaultValue) { $parameterMetadata.DefaultValue } else { "" }
                $testDefault = ($actualDefault -eq $DefaultValue)
                $filters += "the default value$(if ($Negate) {" not"}) to be $(Format-Nicely $DefaultValue)"
    
                if (-not $Negate -and -not $testDefault) {
                    $buts += "the default value was $(Format-Nicely $actualDefault)"
                }
                elseif ($Negate -and $testDefault) {
                    $buts += "the default value was $(Format-Nicely $DefaultValue)"
                }
            }
    
            if ($HasArgumentCompleter) {
                $testArgumentCompleter = $attributes | Where-Object {$_ -is [ArgumentCompleter]}
                $filters += "has ArgumentCompletion"
    
                if (-not $Negate -and -not $testArgumentCompleter) {
                    $buts += "has no ArgumentCompletion"
                }
                elseif ($Negate -and $testArgumentCompleter) {
                    $buts += "has ArgumentCompletion"
                }
            }
        }
    
        if ($buts.Count -ne 0) {
            $filter = Add-SpaceToNonEmptyString ( Join-And $filters -Threshold 3 )
            $but = Join-And $buts
            $failureMessage = "Expected command $($ActualValue.Name)$filter,$(Format-Because $Because) but $but."
    
            return New-Object PSObject -Property @{
                Succeeded      = $false
                FailureMessage = $failureMessage
            }
        }
        else {
            return New-Object PSObject -Property @{ Succeeded = $true }
        }
    }
    
    Add-AssertionOperator -Name         HaveParameter `
        -InternalName Should-HaveParameter `
        -Test         ${function:Should-HaveParameter}
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUreJXU6iAMulCkurnVAGwJZ6o
    # NriggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # BnBjDVKAJyEmrC9+/Ik1vb5aBsUwDQYJKoZIhvcNAQEBBQAEggEAcdDvzCGUgLlS
    # 2AT9hFc7L0eiNVQQTVl/K8D5c/F4IMmdP1WcVuApCVIIA0Tsi3Qr/hPGVaCSWvps
    # ARnDwsH4S1VqZLq+CUeJvJD0dQsO2wq/21j1yVGwjIrO85aMGbWmr4uYITlGYXjr
    # 1dqueg4rpQIi5fXfh+FsIqAy8xMjGMmWQdEjy9JEfp4TgfJR/I9l5WSgCzjBH6Ey
    # H7/lCECpLdbH8HHM8Txq9a1Rxq6HO6le18RdFOCNhX/OGBjAF5aLwyA6EMA8yYGo
    # QhiyXSzimd4eussl/MPZG22ASmc6Yp9GxF8+FSXLyHAKViv7LF7QfgpEA52S2qkm
    # 8QRe7yYii6GCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzU3WjAjBgkqhkiG9w0BCQQx
    # FgQU6qVfe4R3Ta/fR06HKc5z6LNO9y4wDQYJKoZIhvcNAQEBBQAEggEAmeBtHs4y
    # 028INjw+fYdiwuEZtwroarv2qP1DdvzewijznrNTZvVb281DXv+CDGTQAo8GTHH0
    # bOQvyENP78FElPXBqhmr19G7GFMVI8mohp61tVZghXDkS2d6YcIfB+P2/PlH/pq1
    # fUGSyni+lGef4gsjX7kNffM8dK6NgdqnuSyAMODGJQ1XWeqzzMjD11Sc/XweTIuy
    # 1uDdNgQ07y2ak8AwtPfQ66aC2NHbIVzn9OFRfsp2aogP/5CznUKHEsQVoxACKM7C
    # 5yu/dobLDv/f+o0Yi7kIN20rfpao7yS1pjd4p+TX9Bt6Q0sxG/p7cVOHECvz0via
    # PyyNEwZdYCD4Mg==
    # SIG # End signature block
    
  • tools\Functions\Assertions\Match.ps1 Show
    function Should-Match($ActualValue, $RegularExpression, [switch] $Negate, [string] $Because) {
        <#
    .SYNOPSIS
    Uses a regular expression to compare two objects.
    This comparison is not case sensitive.
    
    .EXAMPLE
    "I am a value" | Should -Match "I Am"
    The "I Am" regular expression (RegEx) pattern matches the provided string,
    so the test passes. For case sensitive matches, see MatchExactly.
    .EXAMPLE
    "I am a value" | Should -Match "I am a bad person" # Test will fail
    RegEx pattern does not match the string, and the test fails.
    .EXAMPLE
    "Greg" | Should -Match ".reg" # Test will pass
    This test passes, as "." in RegEx matches any character.
    .EXAMPLE
    "Greg" | Should -Match ([regex]::Escape(".reg"))
    One way to provide literal characters to Match is the [regex]::Escape() method.
    This test fails, because the pattern does not match a period symbol.
    #>
        [bool] $succeeded = $ActualValue -match $RegularExpression
    
        if ($Negate) {
            $succeeded = -not $succeeded
        }
    
        $failureMessage = ''
    
        if (-not $succeeded) {
            if ($Negate) {
                $failureMessage = NotShouldMatchFailureMessage -ActualValue $ActualValue -RegularExpression $RegularExpression -Because $Because
            }
            else {
                $failureMessage = ShouldMatchFailureMessage -ActualValue $ActualValue -RegularExpression $RegularExpression -Because $Because
            }
        }
    
        return New-Object psobject -Property @{
            Succeeded      = $succeeded
            FailureMessage = $failureMessage
        }
    }
    
    function ShouldMatchFailureMessage($ActualValue, $RegularExpression, $Because) {
        return "Expected regular expression $(Format-Nicely $RegularExpression) to match $(Format-Nicely $ActualValue),$(Format-Because $Because) but it did not match."
    }
    
    function NotShouldMatchFailureMessage($ActualValue, $RegularExpression, $Because) {
        return "Expected regular expression $(Format-Nicely $RegularExpression) to not match $(Format-Nicely $ActualValue),$(Format-Because $Because) but it did match."
    }
    
    Add-AssertionOperator -Name         Match `
        -InternalName Should-Match `
        -Test         ${function:Should-Match}
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUwBaMAJxck4pfWcwzDvC7OIMX
    # loSggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # DZoeK7H350xiY9szUk0LTdM2IhowDQYJKoZIhvcNAQEBBQAEggEAm5JowaJC0+y4
    # t/LycSaFCbw4NSbvq4HGPq4NXpJCsVJGKIuPUj9fJF1bvBZtSGe1gUDe4P9+kTKE
    # Fec1y9d7B9qkrNGSvxDMvQAeOoSHXSWchNtXnU5p71/dS7rUP5IMFZ9NPl+Nmcvn
    # Tsd9pj6M+lH7P0kKVnVR+WkRrqOGUjMliViIYRgZ7cTGDTfqJS9zrrMbuNVyM5y1
    # XkBpQqNkXIosDN11uHX2P29opLS55Y2ICXmFtpfdwZJQoJM5X7MloyQ2X1FNnoWp
    # 0QPUzHbgSb6rAyHWoiBZdGsvuRqmWJnU8UTUAgmPQ/Y+M9o1AR9cYll1QBds2f2U
    # mxE+Bt/71KGCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzU4WjAjBgkqhkiG9w0BCQQx
    # FgQUNtxoe816rCG2KdTOL9jM8FOmHSUwDQYJKoZIhvcNAQEBBQAEggEAR/olltgF
    # V/fNcuwprzVlCEyn6n6r8/EoQfauXbCEvT4N4i8gpgsXCeMKJMy/TWvuzu2f5fLk
    # LAvxJCM5qYIl4abLIxvHoXSAt0O2PvKX6F5Jtu0ImGkApG4TnVy/2pUliIHfw4AP
    # tJQc4x1M9L70aqoc/bn3ftUPeyF81319o8o0YenkVVhYm4c+cI4bFgCIkS0vMrVl
    # CgZfbnnQlAX3MIBUW4M6yBgG+5RjDtLUxVR3DcIZoHyDh+VP+rMdYK3HKvqrMoHQ
    # NElQu6KsKubMyZsHr5inxZIH7mS4MNoZYIuaQHq9AfkORvhce2PwUXm7awpBeML7
    # mOxk0AoE2TlKBg==
    # SIG # End signature block
    
  • tools\Functions\Assertions\MatchExactly.ps1 Show
    function Should-MatchExactly($ActualValue, $RegularExpression, [switch] $Negate, [string] $Because) {
        <#
    .SYNOPSIS
    Uses a regular expression to compare two objects.
    This comparison is case sensitive.
    
    .EXAMPLE
    "I am a value" | Should -MatchExactly "I am"
    The "I am" regular expression (RegEx) pattern matches the string.
    This test passes.
    
    .EXAMPLE
    "I am a value" | Should -MatchExactly "I Am"
    Because MatchExactly is case sensitive, this test fails.
    For a case insensitive test, see Match.
    #>
        [bool] $succeeded = $ActualValue -cmatch $RegularExpression
    
        if ($Negate) {
            $succeeded = -not $succeeded
        }
    
        $failureMessage = ''
    
        if (-not $succeeded) {
            if ($Negate) {
                $failureMessage = NotShouldMatchExactlyFailureMessage -ActualValue $ActualValue -RegularExpression $RegularExpression -Because $Because
            }
            else {
                $failureMessage = ShouldMatchExactlyFailureMessage -ActualValue $ActualValue -RegularExpression $RegularExpression -Because $Because
            }
        }
    
        return New-Object psobject -Property @{
            Succeeded      = $succeeded
            FailureMessage = $failureMessage
        }
    }
    
    function ShouldMatchExactlyFailureMessage($ActualValue, $RegularExpression) {
        return "Expected regular expression $(Format-Nicely $RegularExpression) to case sensitively match $(Format-Nicely $ActualValue),$(Format-Because $Because) but it did not match."
    }
    
    function NotShouldMatchExactlyFailureMessage($ActualValue, $RegularExpression) {
        return "Expected regular expression $(Format-Nicely $RegularExpression) to not case sensitively match $(Format-Nicely $ActualValue),$(Format-Because $Because) but it did match."
    }
    
    Add-AssertionOperator -Name         MatchExactly `
        -InternalName Should-MatchExactly `
        -Test         ${function:Should-MatchExactly} `
        -Alias        'CMATCH'
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUjNVNFdeoBKU7ojzuW1WBBhgi
    # WG6ggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # nRDzUIiIu1BibbaxvnyMl1n1qGgwDQYJKoZIhvcNAQEBBQAEggEAHpEQ6I7F4rrV
    # mjQiZa15gtdw8y/ofl10TFAdxlntm+DToOS17UU+Ya/io5Dsa5tI+zJle3vK9QwT
    # mKPAasQ/0PXTF7vfeTZe306O/UbiFmQeosTQxcuIL9OWcBwqpLVmi/EcSMm+41lJ
    # dTt1m/VsBc9fD8HINNwUcKjMIker+kK7cMiwKRLbPPb2Bd23pKInrXqsDMKUiggY
    # unXQLuA8wsJ3I736hGXmyfyUPhlEJsHjCdmEOTKc8HGDeADjvkeQNM3cy5TdiPKp
    # fREHcuLk/0rq6LGbUuO+JJA456twPI0K4f3b9FppwgOYCppSz3Fo+tU66OtkHEFt
    # fHoiwVtkFaGCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzU4WjAjBgkqhkiG9w0BCQQx
    # FgQURRZRGvvng5MeojNifD8Sw9BgA6cwDQYJKoZIhvcNAQEBBQAEggEAgYK4fROI
    # nwGV7E1GZCPTqR8jjakReXPVX07GYA7DE1otLwhLwSTIUUcX9k6jH/2hO01/WalI
    # +lk8wr2v+bHbPwRvRjYJQlqmkFaLMY+yupXWIAUuI4uaCb680W4n0OGTsgGQe0n2
    # V6Rd7JxkMYjtfSeyALahhVkTyVCqxk0xfL8nXINKj0vf+jzYu2xZ2IvDwmQ4Whmy
    # AY8Qk52RxhF2KRhiy6qxrhd8NTOueXiwqlxBiQnfBmAIfMcO4pwzz/mxA/ronNyM
    # qhcvDl6DZTGKoHWjdS256h0KyctsZOHmHZ4+SBb9w8z/a88Rxn16gylhpQvTiFnG
    # RCkoKdrNIisacQ==
    # SIG # End signature block
    
  • tools\Functions\Assertions\PesterThrow.ps1 Show
    function Should-Throw([scriptblock] $ActualValue, $ExpectedMessage, $ErrorId, [type]$ExceptionType, [switch] $Negate, [string] $Because, [switch] $PassThru) {
        <#
    .SYNOPSIS
    Checks if an exception was thrown. Enclose input in a script block.
    
    Warning: The input object must be a ScriptBlock, otherwise it is processed outside of the assertion.
    
    .EXAMPLE
    { foo } | Should -Throw
    Because "foo" isn't a known command, PowerShell throws an error.
    Throw confirms that an error occurred, and successfully passes the test.
    
    .EXAMPLE
    { foo } | Should -Not -Throw
    By using -Not with -Throw, the opposite effect is achieved.
    "Should -Not -Throw" expects no error, but one occurs, and the test fails.
    
    .EXAMPLE
    { $foo = 1 } | Should -Throw
    Assigning a variable does not throw an error.
    If asserting "Should -Throw" but no error occurs, the test fails.
    
    .EXAMPLE
    { $foo = 1 } | Should -Not -Throw
    Assert that assigning a variable should not throw an error.
    It does not throw an error, so the test passes.
    #>
        $actualExceptionMessage = ""
        $actualExceptionWasThrown = $false
        $actualError = $null
        $actualException = $null
        $actualExceptionLine = $null
    
        if ($null -eq $ActualValue) {
            throw (New-Object -TypeName ArgumentNullException -ArgumentList "ActualValue", "Scriptblock not found. Input to 'Throw' and 'Not Throw' must be enclosed in curly braces.")
        }
    
        try {
            do {
                Write-ScriptBlockInvocationHint -Hint "Should -Throw" -ScriptBlock $ActualValue
                $null = & $ActualValue
            } until ($true)
        }
        catch {
            $actualExceptionWasThrown = $true
            $actualError = $_
            $actualException = $_.Exception
            $actualExceptionMessage = $_.Exception.Message
            $actualErrorId = $_.FullyQualifiedErrorId
            $actualExceptionLine = (Get-ExceptionLineInfo $_.InvocationInfo) -replace [System.Environment]::NewLine, "$([System.Environment]::NewLine)    "
        }
    
        [bool] $succeeded = $false
    
        if ($Negate) {
            # this is for Should -Not -Throw. Once *any* exception was thrown we should fail the assertion
            # there is no point in filtering the exception, because there should be none
            $succeeded = -not $actualExceptionWasThrown
            if (-not $succeeded) {
                $failureMessage = "Expected no exception to be thrown,$(Format-Because $Because) but an exception `"$actualExceptionMessage`" was thrown $actualExceptionLine."
                return New-Object psobject -Property @{
                    Succeeded      = $succeeded
                    FailureMessage = $failureMessage
                }
            }
            else {
                return New-Object psobject -Property @{
                    Succeeded = $true
                }
            }
        }
    
        # the rest is for Should -Throw, we must fail the assertion when no exception is thrown
        # or when the exception does not match our filter
    
        function Join-And ($Items, $Threshold = 2) {
    
            if ($null -eq $items -or $items.count -lt $Threshold) {
                $items -join ', '
            }
            else {
                $c = $items.count
                ($items[0..($c - 2)] -join ', ') + ' and ' + $items[-1]
            }
        }
    
        function Add-SpaceToNonEmptyString ([string]$Value) {
            if ($Value) {
                " $Value"
            }
        }
    
        $buts = @()
        $filters = @()
    
        $filterOnExceptionType = $null -ne $ExceptionType
        if ($filterOnExceptionType) {
            $filters += "with type $(Format-Nicely $ExceptionType)"
    
            if ($actualExceptionWasThrown -and $actualException -isnot $ExceptionType) {
                $buts += "the exception type was $(Format-Nicely ($actualException.GetType()))"
            }
        }
    
        $filterOnMessage = -not [string]::IsNullOrEmpty($ExpectedMessage -replace "\s")
        if ($filterOnMessage) {
            $filters += "with message $(Format-Nicely $ExpectedMessage)"
            if ($actualExceptionWasThrown -and (-not (Get-DoValuesMatch $actualExceptionMessage $ExpectedMessage))) {
                $buts += "the message was $(Format-Nicely $actualExceptionMessage)"
            }
        }
    
        $filterOnId = -not [string]::IsNullOrEmpty($ErrorId -replace "\s")
        if ($filterOnId) {
            $filters += "with FullyQualifiedErrorId $(Format-Nicely $ErrorId)"
            if ($actualExceptionWasThrown -and (-not (Get-DoValuesMatch $actualErrorId $ErrorId))) {
                $buts += "the FullyQualifiedErrorId was $(Format-Nicely $actualErrorId)"
            }
        }
    
        if (-not $actualExceptionWasThrown) {
            $buts += "no exception was thrown"
        }
    
        if ($buts.Count -ne 0) {
            $filter = Add-SpaceToNonEmptyString ( Join-And $filters -Threshold 3 )
            $but = Join-And $buts
            $failureMessage = "Expected an exception,$filter to be thrown,$(Format-Because $Because) but $but. $actualExceptionLine".Trim()
    
            return New-Object psobject -Property @{
                Succeeded      = $false
                FailureMessage = $failureMessage
            }
        }
    
        $result = New-Object psobject -Property @{
            Succeeded = $true
        }
    
        if ($PassThru) {
            $result | Add-Member -MemberType NoteProperty -Name 'Data' -Value $actualError
        }
    
        return $result
    }
    
    function Get-DoValuesMatch($ActualValue, $ExpectedValue) {
        #user did not specify any message filter, so any message matches
        if ($null -eq $ExpectedValue ) {
            return $true
        }
    
        return $ActualValue.ToString().IndexOf($ExpectedValue, [System.StringComparison]::InvariantCultureIgnoreCase) -ge 0
    }
    
    function Get-ExceptionLineInfo($info) {
        # $info.PositionMessage has a leading blank line that we need to account for in PowerShell 2.0
        $positionMessage = $info.PositionMessage -split '\r?\n' -match '\S' -join [System.Environment]::NewLine
        return ($positionMessage -replace "^At ", "from ")
    }
    
    function ShouldThrowFailureMessage {
        # to make the should tests happy, for now
    }
    
    function NotShouldThrowFailureMessage {
        # to make the should tests happy, for now
    }
    
    Add-AssertionOperator -Name         Throw `
        -InternalName Should-Throw `
        -Test         ${function:Should-Throw}
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUcDtzYzBS28RXgFpn0gGLPVKV
    # moCggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # oEUs6xX9SyM0zJxxVKBsYqsWDi4wDQYJKoZIhvcNAQEBBQAEggEADu7eJMaOeqOn
    # IK6nqQdspLDnBH99fyVG16lZOUa913bLB2fTCr/CQhlI1kVST3niCyuIAz52caLr
    # NmmIaAxyEDYGe6pswUTsQzJddgv5/OqnirBDfIiIImp/FT0EfrMvAXS3vjfYQGCI
    # 3wdJURreCB1VHxilwby9rxmKEhYVdaBJjrmpe5i9/UVJ2ek5LMWqobOQTMP9JqE9
    # NnjS87OPSk2L2DrZMp0Z08O+5nR8++rABeLD/I+r0MRlq2wSJ44ff3MTRJpo6CGO
    # icnTNi4Q6aJ5lrx68V72IOgP3/WMhrQ5FCht10AdMESRz475fxcq3i1A1NhnjckS
    # xfN51cIvDqGCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzU5WjAjBgkqhkiG9w0BCQQx
    # FgQUBQ8X3wVtmkqL7RgepV51F7hGXb4wDQYJKoZIhvcNAQEBBQAEggEAFMuNCBi2
    # pW2MAC5Xvf/lJ8U7ofc1m1cLovn5GoVtbQDNWx3DcNd4rwj1GrUea0zZCilfV2Au
    # gmwgB+r227gsosjSeHC5mu7hLXaq8aDW4KejeJ1Kit60Vq720A00nm+WGBuj4eo4
    # jHQVMyG+ILoQwaw+HfVYiIvuFiOS0n1HvnFTLsEDuO+ae4uxaRASwIrpIJFrWXOG
    # t+L0ah6ajYlQqeodIiOD5cwl6Ch+biE+570FCpzdBxrm8jFGJrbw2df92EwmsnYo
    # gh7b8giWRfU8rN1kjrWKNmlTAVoWunYyKpMUAkFZjbDQFG0/GpVmGNcxZSGJp2Dx
    # ynuSAPn+L0YMNA==
    # SIG # End signature block
    
  • tools\Functions\Assertions\Set-TestInconclusive.ps1 Show
    function Set-TestInconclusive {
        <#
    
        .SYNOPSIS
        Deprecated. Use `Set-ItResult -Inconclusive` instead
    
        .DESCRIPTION
        Set-TestInconclusive was used inside an It block to mark the test as inconclusive.
        If you need this functionality please use the new Set-ItResult command.
    
        .PARAMETER Message
        Value assigned to the Message parameter will be displayed in the the test result.
    
        .EXAMPLE
        Describe "Example" {
    
            It "My test" {
                Set-TestInconclusive -Message "we forced it to be inconclusive"
            }
    
        }
    
        The test result.
    
        Describing Example
            [?] My test, is inconclusive because we forced it to be inconclusive 58ms
    
        .LINK
        https://github.com/pester/Pester/wiki/Set%E2%80%90TestInconclusive
    #>
        [CmdletBinding()]
        param (
            [string] $Message
        )
    
        if (!$script:HasAlreadyWarnedAboutDeprecation) {
            Write-Warning 'DEPRECATED: Set-TestInconclusive was deprecated and will be removed in the future. Please update your scripts to use `Set-ItResult -Inconclusive -Because $Message`.'
            $script:HasAlreadyWarnedAboutDeprecation = $true
        }
    
        Set-ItResult -Inconclusive -Because $Message
    }
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUa/cVHBuhsNVdoBXr3QSJwkoB
    # kYiggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # LzbdFoMldf4RturRf3XdZRrN52gwDQYJKoZIhvcNAQEBBQAEggEASMSL0XfqtihF
    # CGXLo19/q7Cmliwjo2RceblcH7jKdhc2QVcRhHmgiRNWmLWKSovocs6I8rOoIiwu
    # sSDpZO7GswEtNUvx8m7JukkKsUr2k4anHPwzVgNoA3vdLdKXPw9ujemGI8PU19lb
    # RZ9TVT4Wy5vr5cvuiN8p5GKT8yu5xtsuvZLHVqEQknngchQ20AbEWPJBSId5qLFL
    # 6/Y6nsozmp2rTX1rOibf6RBA6hZZh3EqwhLHxe/PaKxC3RS44w+dxXI9enIoRXGx
    # oS5Jynvt/u0LDMC/ccDL8FlLsnJEWyrsAZPZyfq+OfCYkJjizmgIKOC5NiwCiWdg
    # nqE2hgOczaGCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0ODAwWjAjBgkqhkiG9w0BCQQx
    # FgQUJfB5vuqnbPeS/XcRBg6et0sH9TgwDQYJKoZIhvcNAQEBBQAEggEAQVyrx+BB
    # dQ7vkamuQDS8k4dvqU+KkS3gjxdJH9J4AzI7QFa33qbZw8XjoF6ltOuSpdpHz3AQ
    # OOWMcvoVlDdeC9rST+QMMTuQqR+zqampoFMtuqhoBCwjJZeo+zT7eWcGrl0fE+mu
    # LQM33ElsAFDe9Q2wNP/XAKc2bVtnJxNhLrZ1XUMck46WuGysaW2RR3X+uQSPWP5Z
    # P28nKOGxBFUgqkliWWmkBaOJp9MqfcKwmFmAzOJZcsPQxtlJ8p8tCR6ih3SZXion
    # MLX85on09jgvyNg9xjKGaJc53yKnUq/8gE6HknjTL55MZyWiTFX0P0xtQcJAtebQ
    # ojiuHsknS0VPxw==
    # SIG # End signature block
    
  • tools\Functions\Assertions\Should.ps1 Show
    function Parse-ShouldArgs([object[]] $shouldArgs) {
        if ($null -eq $shouldArgs) {
            $shouldArgs = @()
        }
    
        $parsedArgs = @{
            PositiveAssertion = $true
            ExpectedValue     = $null
        }
    
        $assertionMethodIndex = 0
        $expectedValueIndex = 1
    
        if ($shouldArgs.Count -gt 0 -and $shouldArgs[0] -eq "not") {
            $parsedArgs.PositiveAssertion = $false
            $assertionMethodIndex += 1
            $expectedValueIndex += 1
        }
    
        if ($assertionMethodIndex -lt $shouldArgs.Count) {
            $parsedArgs.AssertionMethod = "$($shouldArgs[$assertionMethodIndex])"
        }
        else {
            throw 'You cannot call Should without specifying an assertion method.'
        }
    
        if ($expectedValueIndex -lt $shouldArgs.Count) {
            $parsedArgs.ExpectedValue = $shouldArgs[$expectedValueIndex]
        }
    
        return $parsedArgs
    }
    
    function Get-FailureMessage($assertionEntry, $negate, $value, $expected) {
        if ($negate) {
            $failureMessageFunction = $assertionEntry.GetNegativeFailureMessage
        }
        else {
            $failureMessageFunction = $assertionEntry.GetPositiveFailureMessage
        }
    
        return (& $failureMessageFunction $value $expected)
    }
    
    function New-ShouldErrorRecord ([string] $Message, [string] $File, [string] $Line, [string] $LineText) {
        $exception = & $SafeCommands['New-Object'] Exception $Message
        $errorID = 'PesterAssertionFailed'
        $errorCategory = [Management.Automation.ErrorCategory]::InvalidResult
        # we use ErrorRecord.TargetObject to pass structured information about the error to a reporting system.
        $targetObject = @{Message = $Message; File = $File; Line = $Line; LineText = $LineText}
        $errorRecord = & $SafeCommands['New-Object'] Management.Automation.ErrorRecord $exception, $errorID, $errorCategory, $targetObject
        return $errorRecord
    }
    
    function Should {
        <#
        .SYNOPSIS
        Should is a keyword what is used to define an assertion inside It block.
    
        .DESCRIPTION
        Should is a keyword what is used to define an assertion inside the It block.
        Should provides assertion methods for verify assertion e.g. comparing objects.
        If assertion is not met the test fails and an exception is throwed up.
    
        Should can be used more than once in the It block if more than one assertion
        need to be verified. Each Should keywords need to be located in a new line.
        Test will be passed only when all assertion will be met (logical conjuction).
    
        .LINK
        https://github.com/pester/Pester/wiki/Should
    
        .LINK
        about_Should
        about_Pester
    #>
    
        [CmdletBinding(DefaultParameterSetName = 'Legacy')]
        param (
            [Parameter(ParameterSetName = 'Legacy', Position = 0)]
            [object] $__LegacyArg1,
    
            [Parameter(ParameterSetName = 'Legacy', Position = 1)]
            [object] $__LegacyArg2,
    
            [Parameter(ParameterSetName = 'Legacy', Position = 2)]
            [object] $__LegacyArg3,
    
            [Parameter(ValueFromPipeline = $true)]
            [object] $ActualValue
        )
    
        dynamicparam {
            Get-AssertionDynamicParams
        }
    
        begin {
            $inputArray = New-Object System.Collections.Generic.List[PSObject]
    
            if ($PSCmdlet.ParameterSetName -eq 'Legacy') {
                $parsedArgs = Parse-ShouldArgs ($__LegacyArg1, $__LegacyArg2, $__LegacyArg3)
                $entry = Get-AssertionOperatorEntry -Name $parsedArgs.AssertionMethod
                if ($null -eq $entry) {
                    throw "'$($parsedArgs.AssertionMethod)' is not a valid Should operator."
                }
            }
        }
    
        process {
            $inputArray.Add($ActualValue)
        }
    
        end {
            $lineNumber = $MyInvocation.ScriptLineNumber
            $lineText = $MyInvocation.Line.TrimEnd("$([System.Environment]::NewLine)")
            $file = $MyInvocation.ScriptName
    
            if ($PSCmdlet.ParameterSetName -eq 'Legacy') {
                if ($inputArray.Count -eq 0) {
                    Invoke-LegacyAssertion $entry $parsedArgs $null $file $lineNumber $lineText
                }
                elseif ($entry.SupportsArrayInput) {
                    Invoke-LegacyAssertion $entry $parsedArgs $inputArray.ToArray() $file $lineNumber $lineText
                }
                else {
                    foreach ($object in $inputArray) {
                        Invoke-LegacyAssertion $entry $parsedArgs $object $file $lineNumber $lineText
                    }
                }
            }
            else {
                $negate = $false
                if ($PSBoundParameters.ContainsKey('Not')) {
                    $negate = [bool]$PSBoundParameters['Not']
                }
    
                $null = $PSBoundParameters.Remove('ActualValue')
                $null = $PSBoundParameters.Remove($PSCmdlet.ParameterSetName)
                $null = $PSBoundParameters.Remove('Not')
    
                $entry = Get-AssertionOperatorEntry -Name $PSCmdlet.ParameterSetName
    
                if ($inputArray.Count -eq 0) {
                    Invoke-Assertion $entry $PSBoundParameters $null $file $lineNumber $lineText -Negate:$negate
                }
                elseif ($entry.SupportsArrayInput) {
                    Invoke-Assertion $entry $PSBoundParameters $inputArray.ToArray() $file $lineNumber $lineText -Negate:$negate
                }
                else {
                    foreach ($object in $inputArray) {
                        Invoke-Assertion $entry $PSBoundParameters $object $file $lineNumber $lineText -Negate:$negate
                    }
                }
            }
        }
    }
    
    function Invoke-LegacyAssertion($assertionEntry, $shouldArgs, $valueToTest, $file, $lineNumber, $lineText) {
        # $expectedValueSplat = @(
        #     if ($null -ne $shouldArgs.ExpectedValue)
        #     {
        #         ,$shouldArgs.ExpectedValue
        #     }
        # )
    
        $negate = -not $shouldArgs.PositiveAssertion
    
        $testResult = (& $assertionEntry.Test $valueToTest $shouldArgs.ExpectedValue -Negate:$negate)
        if (-not $testResult.Succeeded) {
            throw ( New-ShouldErrorRecord -Message $testResult.FailureMessage -File $file -Line $lineNumber -LineText $lineText )
        }
    }
    
    function Invoke-Assertion {
        param (
            [object] $AssertionEntry,
            [System.Collections.IDictionary] $BoundParameters,
            [object] $valuetoTest,
            [string] $File,
            [int] $LineNumber,
            [string] $LineText,
            [switch] $Negate
        )
    
        $testResult = & $AssertionEntry.Test -ActualValue $valuetoTest -Negate:$Negate @BoundParameters
        if (-not $testResult.Succeeded) {
            throw ( New-ShouldErrorRecord -Message $testResult.FailureMessage -File $file -Line $lineNumber -LineText $lineText )
        }
        else {
            #extract data to return if there are any on the object
            $data = $testResult.psObject.Properties.Item('Data')
            if ($data) {
                $data.Value
            }
        }
    }
    
    function Format-Because ([string] $Because) {
        if ($null -eq $Because) {
            return
        }
    
        $bcs = $Because.Trim()
        if ([string]::IsNullOrEmpty($bcs)) {
            return
        }
    
        " because $($bcs -replace 'because\s'),"
    }
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUHqrMIWcb3tp5qylUuVcgfSnH
    # 7QuggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # H5MZGTpJV0YsrTKnIPPzPOZjq1swDQYJKoZIhvcNAQEBBQAEggEADzXhkuQIJmhI
    # FfLTsoEi3xwveATUC5TsUWnUOCsXniGfFQ2fjeip18KhleOgKl7kZtvJXYdgDzdK
    # cGBfv/N19zzFVZjfm3whLxIMc/VhDN1i1153U4KVnC10pwq0Oh4S0gJxkvks8Shk
    # GS5rTcNFcQiRmGrijUZ8dbfE6wGCWs9hiuwu7AuYnbiRvLSapxUnESHWD5/i4CPF
    # dpg9De5gB/aYUUCPE5AiXJ14WfZQsMDKgxfoiPie3AHghUBieZxauliCv26O1AH5
    # DBOqLcDuJEaS70K6UWQ1lUa1AinfWis4Qfwj9ar0yXWziZ0EGSkvRwgJJkDPsNuQ
    # E91ppdadP6GCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0ODAwWjAjBgkqhkiG9w0BCQQx
    # FgQUblfYaPuu0o5s+MJSJVdD7v2w8GUwDQYJKoZIhvcNAQEBBQAEggEAl+Uix85W
    # 14o6Cp6s0TK2yelWWs9JTgCqK5QvEYW6bjcNL/CUHu0F9FpXSF92gKmawM3nIxvT
    # jIFlNGYev3yjnFnsoMtn3rADDd0PElyvZ2bA7YKsMtvG1oSNlDj6q/n5FQfysWio
    # zPQXD3DhOOF6O/kj4ogJnDEahk4A7iFDDaMo9z0y9Ud+Rp3+hHAj1NhJh7uK3T9D
    # gnboZ87uFszMUgutKfXkhiBwzGnNHaorcIXgZQlrmYIvdEOUDflNXyDh16nXgtQ8
    # Ph3bXIivDUTX4H+kwOwWkhmlZZmxSycY3ScGVH9sEqDjzGfuONjgdVs1iDtyPj5R
    # +jc23n5baiEtUg==
    # SIG # End signature block
    
  • tools\Functions\Context.ps1 Show
    function Context {
        <#
    .SYNOPSIS
    Provides logical grouping of It blocks within a single Describe block.
    
    .DESCRIPTION
    Provides logical grouping of It blocks within a single Describe block.
    Any Mocks defined inside a Context are removed at the end of the Context scope,
    as are any files or folders added to the TestDrive during the Context block's
    execution. Any BeforeEach or AfterEach blocks defined inside a Context also only
    apply to tests within that Context .
    
    .PARAMETER Name
    The name of the Context. This is a phrase describing a set of tests within a describe.
    
    .PARAMETER Tag
    Optional parameter containing an array of strings.  When calling Invoke-Pester,
    it is possible to specify a -Tag parameter which will only execute Context blocks
    containing the same Tag.
    
    .PARAMETER Fixture
    Script that is executed. This may include setup specific to the context
    and one or more It blocks that validate the expected outcomes.
    
    .EXAMPLE
    function Add-Numbers($a, $b) {
        return $a + $b
    }
    
    Describe "Add-Numbers" {
    
        Context "when root does not exist" {
             It "..." { ... }
        }
    
        Context "when root does exist" {
            It "..." { ... }
            It "..." { ... }
            It "..." { ... }
        }
    }
    
    .LINK
    https://github.com/pester/Pester/wiki/Context
    
    .LINK
    Describe
    It
    BeforeEach
    AfterEach
    about_Should
    about_Mocking
    about_TestDrive
    
    #>
        param(
            [Parameter(Mandatory = $true, Position = 0)]
            [string] $Name,
    
            [Alias('Tags')]
            [string[]] $Tag = @(),
    
            [Parameter(Position = 1)]
            [ScriptBlock] $Fixture
        )
        if ($Fixture -eq $null) {
            if ($Name.Contains("`n")) {
                throw "Test fixture name has multiple lines and no test fixture is provided. (Have you provided a name for the test group?)"
            }
            else {
                throw 'No test fixture is provided. (Have you put the open curly brace on the next line?)'
            }
        }
        if ($null -eq (& $SafeCommands['Get-Variable'] -Name Pester -ValueOnly -ErrorAction $script:IgnoreErrorPreference)) {
            # User has executed a test script directly instead of calling Invoke-Pester
            $sessionState = Set-SessionStateHint -PassThru -Hint "Caller - Captured in Context" -SessionState $PSCmdlet.SessionState
            $Pester = New-PesterState -Path (& $SafeCommands['Resolve-Path'] .) -TestNameFilter $null -TagFilter @() -SessionState SessionState
            $script:mockTable = @{}
        }
    
        DescribeImpl @PSBoundParameters -CommandUsed 'Context' -Pester $Pester -DescribeOutputBlock ${function:Write-Describe} -TestOutputBlock ${function:Write-PesterResult} -NoTestRegistry:('Windows' -ne (GetPesterOs))
    }
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQU8DQFjWeiXlsQfT/ofwk8tt8U
    # iKeggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # Pg5m5IVIYCEBzj8944309PtrdSAwDQYJKoZIhvcNAQEBBQAEggEAmFLu+PfUhLNz
    # otu9W5tdZdXRTCs8YkrErQ2xOW+qBpq++AZcZZceTJnn28GUJ32qSKVDh2nw3m/Y
    # NCbf754lx/DJ/MyplLmkZQrEyw9Eq9ImAUbkqNIq0FUxI3aBUgsDA8tLZid46+v0
    # T1zjPbB1dkKC4AsapfWCCHu49fmyQY2V/6eRbuEtT6vBTjuBWUB09/tLnJvCsrX/
    # kJC87kNqJIIhzh0ZapMpSKZiSD2KsWp8kcldPioIhCwe9hmp8JlKH1oexaP1w2ON
    # d3BUe1sYafTD0tj5T1aiS3JHSINDDkb1kNUhoaEJOJpRcImod6+L9podS3LDYqPQ
    # sFb3Y6M+XaGCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzMzWjAjBgkqhkiG9w0BCQQx
    # FgQU30YicOtA9YrO6KU9diBDUWYRAq4wDQYJKoZIhvcNAQEBBQAEggEAb2+CUf0c
    # ahi6zv1annhWcinPB+bKKjZQoUGi7j6H/QAcYXGzWiI2KqmVhXK4pXVN6Q0ja54A
    # xx2Y34C03c4gQ5AK2XQWlJ2a+wQuCX85go6UhYJOG57r+2g3fxbiATuSZWB409Ex
    # e4UBy0dk8IIHMl/tb7qXHT2aJe7UV3cWJV8jaq1/ZmQ0CZmqgU/miAtiCL07wa+2
    # S8LkOquxZCNrByknjmaMQLcNBQoicwc5c1U27Nba0aZj+gcZIlTsscTL4TeofRJK
    # dkFdAcHLeXy3l95t611nT+dl5qXWVzGBd7MrJQtbcKC/lof+EOl4eypuqtTc5xmR
    # 1ycoeabEK/c9AQ==
    # SIG # End signature block
    
  • tools\Functions\Coverage.ps1 Show
    if ($PSVersionTable.PSVersion.Major -le 2) {
        function Exit-CoverageAnalysis { }
        function Get-CoverageReport { }
        function Write-CoverageReport { }
        function Enter-CoverageAnalysis {
            param ( $CodeCoverage )
    
            if ($CodeCoverage) {
                & $SafeCommands['Write-Error'] 'Code coverage analysis requires PowerShell 3.0 or later.'
            }
        }
    
        return
    }
    
    function Enter-CoverageAnalysis {
        [CmdletBinding()]
        param (
            [object[]] $CodeCoverage,
            [object] $PesterState
        )
    
        $coverageInfo =
        foreach ($object in $CodeCoverage) {
            Get-CoverageInfoFromUserInput -InputObject $object
        }
    
        $PesterState.CommandCoverage = @(Get-CoverageBreakpoints -CoverageInfo $coverageInfo)
    }
    
    function Exit-CoverageAnalysis {
        param ([object] $PesterState)
    
        & $SafeCommands['Set-StrictMode'] -Off
    
        # PSScriptAnalyzer it will flag this line because $null is on the LHS of -ne.
        # BUT that is correct in this case. We are filtering the list of breakpoints
        # to only get those that are not $null
        # (like if we did $breakpoints | where {$_ -ne $null})
        # so DON'T change this.
        $breakpoints = @($PesterState.CommandCoverage.Breakpoint) -ne $null
        if ($breakpoints.Count -gt 0) {
            & $SafeCommands['Remove-PSBreakpoint'] -Breakpoint $breakpoints
        }
    }
    
    function Get-CoverageInfoFromUserInput {
        param (
            [Parameter(Mandatory = $true)]
            [object]
            $InputObject
        )
    
        if ($InputObject -is [System.Collections.IDictionary]) {
            $unresolvedCoverageInfo = Get-CoverageInfoFromDictionary -Dictionary $InputObject
        }
        else {
            $Path = $InputObject -as [string]
    
            # Auto-detect IncludeTests-value from path-input
            $IncludeTests = $Path -match '\.tests\.ps1$'
    
            $unresolvedCoverageInfo = New-CoverageInfo -Path $Path -IncludeTests $IncludeTests
        }
    
        Resolve-CoverageInfo -UnresolvedCoverageInfo $unresolvedCoverageInfo
    }
    
    function New-CoverageInfo {
        param ([string] $Path, [string] $Class = $null, [string] $Function = $null, [int] $StartLine = 0, [int] $EndLine = 0, [bool] $IncludeTests = $false)
    
        return [pscustomobject]@{
            Path         = $Path
            Class        = $Class
            Function     = $Function
            StartLine    = $StartLine
            EndLine      = $EndLine
            IncludeTests = $IncludeTests
        }
    }
    
    function Get-CoverageInfoFromDictionary {
        param ([System.Collections.IDictionary] $Dictionary)
    
        [string] $path = Get-DictionaryValueFromFirstKeyFound -Dictionary $Dictionary -Key 'Path', 'p'
        if ([string]::IsNullOrEmpty($path)) {
            throw "Coverage value '$Dictionary' is missing required Path key."
        }
    
        $startLine = Get-DictionaryValueFromFirstKeyFound -Dictionary $Dictionary -Key 'StartLine', 'Start', 's'
        $endLine = Get-DictionaryValueFromFirstKeyFound -Dictionary $Dictionary -Key 'EndLine', 'End', 'e'
        [string] $class = Get-DictionaryValueFromFirstKeyFound -Dictionary $Dictionary -Key 'Class', 'c'
        [string] $function = Get-DictionaryValueFromFirstKeyFound -Dictionary $Dictionary -Key 'Function', 'f'
        $includeTests = Get-DictionaryValueFromFirstKeyFound -Dictionary $Dictionary -Key 'IncludeTests'
    
        $startLine = Convert-UnknownValueToInt -Value $startLine -DefaultValue 0
        $endLine = Convert-UnknownValueToInt -Value $endLine -DefaultValue 0
        [bool] $includeTests = Convert-UnknownValueToInt -Value $includeTests -DefaultValue 0
    
        return New-CoverageInfo -Path $path -StartLine $startLine -EndLine $endLine -Class $class -Function $function -IncludeTests $includeTests
    }
    
    function Convert-UnknownValueToInt {
        param ([object] $Value, [int] $DefaultValue = 0)
    
        try {
            return [int] $Value
        }
        catch {
            return $DefaultValue
        }
    }
    
    function Resolve-CoverageInfo {
        param ([psobject] $UnresolvedCoverageInfo)
    
        $path = $UnresolvedCoverageInfo.Path
    
        $testsPattern = '\.tests\.ps1$'
        $includeTests = $UnresolvedCoverageInfo.IncludeTests
    
        try {
            $resolvedPaths = & $SafeCommands['Resolve-Path'] -Path $path -ErrorAction Stop |
                & $SafeCommands['Where-Object'] { $includeTests -or $_.Path -notmatch $testsPattern }
        }
        catch {
            & $SafeCommands['Write-Error'] "Could not resolve coverage path '$path': $($_.Exception.Message)"
            return
        }
    
        $filePaths =
        foreach ($resolvedPath in $resolvedPaths) {
            $item = & $SafeCommands['Get-Item'] -LiteralPath $resolvedPath
            if ($item -is [System.IO.FileInfo] -and ('.ps1', '.psm1') -contains $item.Extension) {
                $item.FullName
            }
            elseif (-not $item.PsIsContainer) {
                & $SafeCommands['Write-Warning'] "CodeCoverage path '$path' resolved to a non-PowerShell file '$($item.FullName)'; this path will not be part of the coverage report."
            }
        }
    
        $params = @{
            StartLine = $UnresolvedCoverageInfo.StartLine
            EndLine   = $UnresolvedCoverageInfo.EndLine
            Class     = $UnresolvedCoverageInfo.Class
            Function  = $UnresolvedCoverageInfo.Function
        }
    
        foreach ($filePath in $filePaths) {
            $params['Path'] = $filePath
            New-CoverageInfo @params
        }
    }
    
    function Get-CoverageBreakpoints {
        [CmdletBinding()]
        param (
            [object[]] $CoverageInfo
        )
    
        $fileGroups = @($CoverageInfo | & $SafeCommands['Group-Object'] -Property Path)
        foreach ($fileGroup in $fileGroups) {
            & $SafeCommands['Write-Verbose'] "Initializing code coverage analysis for file '$($fileGroup.Name)'"
            $totalCommands = 0
            $analyzedCommands = 0
    
            :commandLoop
            foreach ($command in Get-CommandsInFile -Path $fileGroup.Name) {
                $totalCommands++
    
                foreach ($coverageInfoObject in $fileGroup.Group) {
                    if (Test-CoverageOverlapsCommand -CoverageInfo $coverageInfoObject -Command $command) {
                        $analyzedCommands++
                        New-CoverageBreakpoint -Command $command
                        continue commandLoop
                    }
                }
            }
    
            & $SafeCommands['Write-Verbose'] "Analyzing $analyzedCommands of $totalCommands commands in file '$($fileGroup.Name)' for code coverage"
        }
    }
    
    function Get-CommandsInFile {
        param ([string] $Path)
    
        $errors = $null
        $tokens = $null
        $ast = [System.Management.Automation.Language.Parser]::ParseFile($Path, [ref] $tokens, [ref] $errors)
    
        if ($PSVersionTable.PSVersion.Major -ge 5) {
            # In PowerShell 5.0, dynamic keywords for DSC configurations are represented by the DynamicKeywordStatementAst
            # class.  They still trigger breakpoints, but are not a child class of CommandBaseAst anymore.
    
            $predicate = {
                $args[0] -is [System.Management.Automation.Language.DynamicKeywordStatementAst] -or
                $args[0] -is [System.Management.Automation.Language.CommandBaseAst]
            }
        }
        else {
            $predicate = { $args[0] -is [System.Management.Automation.Language.CommandBaseAst] }
        }
    
        $searchNestedScriptBlocks = $true
        $ast.FindAll($predicate, $searchNestedScriptBlocks)
    }
    
    function Test-CoverageOverlapsCommand {
        param ([object] $CoverageInfo, [System.Management.Automation.Language.Ast] $Command)
    
        if ($CoverageInfo.Class -or $CoverageInfo.Function) {
            Test-CommandInScope -Command $Command -Class $CoverageInfo.Class -Function $CoverageInfo.Function
        }
        else {
            Test-CoverageOverlapsCommandByLineNumber @PSBoundParameters
        }
    
    }
    
    function Test-CommandInScope {
        param ([System.Management.Automation.Language.Ast] $Command, [string] $Class, [string] $Function)
    
        $classResult = !$Class
        $functionResult = !$Function
        for ($ast = $Command; $null -ne $ast; $ast = $ast.Parent) {
            if (!$classResult -and $PSVersionTable.PSVersion.Major -ge 5) {
                # Classes have been introduced in PowerShell 5.0
                $classAst = $ast -as [System.Management.Automation.Language.TypeDefinitionAst]
                if ($null -ne $classAst -and $classAst.Name -like $Class) {
                    $classResult = $true
                }
            }
            if (!$functionResult) {
                $functionAst = $ast -as [System.Management.Automation.Language.FunctionDefinitionAst]
                if ($null -ne $functionAst -and $functionAst.Name -like $Function) {
                    $functionResult = $true
                }
            }
            if ($classResult -and $functionResult) {
                return $true
            }
        }
    
        return $false
    }
    
    function Test-CoverageOverlapsCommandByLineNumber {
        param ([object] $CoverageInfo, [System.Management.Automation.Language.Ast] $Command)
    
        $commandStart = $Command.Extent.StartLineNumber
        $commandEnd = $Command.Extent.EndLineNumber
        $coverStart = $CoverageInfo.StartLine
        $coverEnd = $CoverageInfo.EndLine
    
        # An EndLine value of 0 means to cover the entire rest of the file from StartLine
        # (which may also be 0)
        if ($coverEnd -le 0) {
            $coverEnd = [int]::MaxValue
        }
    
        return (Test-RangeContainsValue -Value $commandStart -Min $coverStart -Max $coverEnd) -or
        (Test-RangeContainsValue -Value $commandEnd -Min $coverStart -Max $coverEnd)
    }
    
    function Test-RangeContainsValue {
        param ([int] $Value, [int] $Min, [int] $Max)
        return $Value -ge $Min -and $Value -le $Max
    }
    
    function New-CoverageBreakpoint {
        param ([System.Management.Automation.Language.Ast] $Command)
    
        if (IsIgnoredCommand -Command $Command) {
            return
        }
    
        $params = @{
            Script = $Command.Extent.File
            Line   = $Command.Extent.StartLineNumber
            Column = $Command.Extent.StartColumnNumber
            Action = { }
        }
    
        $breakpoint = & $SafeCommands['Set-PSBreakpoint'] @params
    
        [pscustomobject] @{
            File        = $Command.Extent.File
            Class       = Get-ParentClassName -Ast $Command
            Function    = Get-ParentFunctionName -Ast $Command
            StartLine   = $Command.Extent.StartLineNumber
            EndLine     = $Command.Extent.EndLineNumber
            StartColumn = $Command.Extent.StartColumnNumber
            EndColumn   = $Command.Extent.EndColumnNumber
            Command     = Get-CoverageCommandText -Ast $Command
            Breakpoint  = $breakpoint
        }
    }
    
    function IsIgnoredCommand {
        param ([System.Management.Automation.Language.Ast] $Command)
    
        if (-not $Command.Extent.File) {
            # This can happen if the script contains "configuration" or any similarly implemented
            # dynamic keyword.  PowerShell modifies the script code and reparses it in memory, leading
            # to AST elements with no File in their Extent.
            return $true
        }
    
        if ($PSVersionTable.PSVersion.Major -ge 4) {
            if ($Command.Extent.Text -eq 'Configuration') {
                # More DSC voodoo.  Calls to "configuration" generate breakpoints, but their HitCount
                # stays zero (even though they are executed.)  For now, ignore them, unless we can come
                # up with a better solution.
                return $true
            }
    
            if (IsChildOfHashtableDynamicKeyword -Command $Command) {
                # The lines inside DSC resource declarations don't trigger their breakpoints when executed,
                # just like the "configuration" keyword itself.  I don't know why, at this point, but just like
                # configuration, we'll ignore it so it doesn't clutter up the coverage analysis with useless junk.
                return $true
            }
        }
    
        if (IsClosingLoopCondition -Command $Command) {
            # For some reason, the closing expressions of do/while and do/until loops don't trigger their breakpoints.
            # To avoid useless clutter, we'll ignore those lines as well.
            return $true
        }
    
        return $false
    }
    
    function IsChildOfHashtableDynamicKeyword {
        param ([System.Management.Automation.Language.Ast] $Command)
    
        for ($ast = $Command.Parent; $null -ne $ast; $ast = $ast.Parent) {
            if ($PSVersionTable.PSVersion.Major -ge 5) {
                # The ast behaves differently for DSC resources with version 5+.  There's a new DynamicKeywordStatementAst class,
                # and they no longer are represented by CommandAst objects.
    
                if ($ast -is [System.Management.Automation.Language.DynamicKeywordStatementAst] -and
                    $ast.CommandElements[-1] -is [System.Management.Automation.Language.HashtableAst]) {
                    return $true
                }
            }
            else {
                if ($ast -is [System.Management.Automation.Language.CommandAst] -and
                    $null -ne $ast.DefiningKeyword -and
                    $ast.DefiningKeyword.BodyMode -eq [System.Management.Automation.Language.DynamicKeywordBodyMode]::Hashtable) {
                    return $true
                }
            }
        }
    
        return $false
    }
    
    function IsClosingLoopCondition {
        param ([System.Management.Automation.Language.Ast] $Command)
    
        $ast = $Command
    
        while ($null -ne $ast.Parent) {
            if (($ast.Parent -is [System.Management.Automation.Language.DoWhileStatementAst] -or
                    $ast.Parent -is [System.Management.Automation.Language.DoUntilStatementAst]) -and
                $ast.Parent.Condition -eq $ast) {
                return $true
            }
    
            $ast = $ast.Parent
        }
    
        return $false
    }
    
    function Get-ParentClassName {
        param ([System.Management.Automation.Language.Ast] $Ast)
    
        if ($PSVersionTable.PSVersion.Major -ge 5) {
            # Classes have been introduced in PowerShell 5.0
    
            $parent = $Ast.Parent
    
            while ($null -ne $parent -and $parent -isnot [System.Management.Automation.Language.TypeDefinitionAst]) {
                $parent = $parent.Parent
            }
        }
    
        if ($null -eq $parent) {
            return ''
        }
        else {
            return $parent.Name
        }
    }
    
    function Get-ParentFunctionName {
        param ([System.Management.Automation.Language.Ast] $Ast)
    
        $parent = $Ast.Parent
    
        while ($null -ne $parent -and $parent -isnot [System.Management.Automation.Language.FunctionDefinitionAst]) {
            $parent = $parent.Parent
        }
    
        if ($null -eq $parent) {
            return ''
        }
        else {
            return $parent.Name
        }
    }
    
    function Get-CoverageCommandText {
        param ([System.Management.Automation.Language.Ast] $Ast)
    
        $reportParentExtentTypes = @(
            [System.Management.Automation.Language.ReturnStatementAst]
            [System.Management.Automation.Language.ThrowStatementAst]
            [System.Management.Automation.Language.AssignmentStatementAst]
            [System.Management.Automation.Language.IfStatementAst]
        )
    
        $parent = Get-ParentNonPipelineAst -Ast $Ast
    
        if ($null -ne $parent) {
            if ($parent -is [System.Management.Automation.Language.HashtableAst]) {
                return Get-KeyValuePairText -HashtableAst $parent -ChildAst $Ast
            }
            elseif ($reportParentExtentTypes -contains $parent.GetType()) {
                return $parent.Extent.Text
            }
        }
    
        return $Ast.Extent.Text
    }
    
    function Get-ParentNonPipelineAst {
        param ([System.Management.Automation.Language.Ast] $Ast)
    
        $parent = $null
        if ($null -ne $Ast) {
            $parent = $Ast.Parent
        }
    
        while ($parent -is [System.Management.Automation.Language.PipelineAst]) {
            $parent = $parent.Parent
        }
    
        return $parent
    }
    
    function Get-KeyValuePairText {
        param (
            [System.Management.Automation.Language.HashtableAst] $HashtableAst,
            [System.Management.Automation.Language.Ast] $ChildAst
        )
    
        & $SafeCommands['Set-StrictMode'] -Off
    
        foreach ($keyValuePair in $HashtableAst.KeyValuePairs) {
            if ($keyValuePair.Item2.PipelineElements -contains $ChildAst) {
                return '{0} = {1}' -f $keyValuePair.Item1.Extent.Text, $keyValuePair.Item2.Extent.Text
            }
        }
    
        # This shouldn't happen, but just in case, default to the old output of just the expression.
        return $ChildAst.Extent.Text
    }
    
    function Get-CoverageMissedCommands {
        param ([object[]] $CommandCoverage)
        $CommandCoverage | & $SafeCommands['Where-Object'] { $_.Breakpoint.HitCount -eq 0 }
    }
    
    function Get-CoverageHitCommands {
        param ([object[]] $CommandCoverage)
        $CommandCoverage | & $SafeCommands['Where-Object'] { $_.Breakpoint.HitCount -gt 0 }
    }
    
    function Get-CoverageReport {
        param ([object] $PesterState)
    
        $properties = @(
            'File'
            @{ Name = 'Line'; Expression = { $_.StartLine } }
            'StartLine'
            'EndLine'
            'StartColumn'
            'EndColumn'
            'Class'
            'Function'
            'Command'
            @{ Name = 'HitCount'; Expression = { $_.Breakpoint.HitCount } }
        )
        $missedCommands = @(Get-CoverageMissedCommands -CommandCoverage $PesterState.CommandCoverage | & $SafeCommands['Select-Object'] $properties)
        $hitCommands = @(Get-CoverageHitCommands -CommandCoverage $PesterState.CommandCoverage | & $SafeCommands['Select-Object'] $properties)
        $analyzedFiles = @($PesterState.CommandCoverage | & $SafeCommands['Select-Object'] -ExpandProperty File -Unique)
    
        [pscustomobject] @{
            NumberOfCommandsAnalyzed = $PesterState.CommandCoverage.Count
            NumberOfFilesAnalyzed    = $analyzedFiles.Count
            NumberOfCommandsExecuted = $hitCommands.Count
            NumberOfCommandsMissed   = $missedCommands.Count
            MissedCommands           = $missedCommands
            HitCommands              = $hitCommands
            AnalyzedFiles            = $analyzedFiles
        }
    }
    
    function Get-CommonParentPath {
        param ([string[]] $Path)
    
        $pathsToTest = @(
            $Path |
                Normalize-Path |
                & $SafeCommands['Select-Object'] -Unique
        )
    
        if ($pathsToTest.Count -gt 0) {
            $parentPath = & $SafeCommands['Split-Path'] -Path $pathsToTest[0] -Parent
    
            while ($parentPath.Length -gt 0) {
                $nonMatches = $pathsToTest -notmatch "^$([regex]::Escape($parentPath))"
    
                if ($nonMatches.Count -eq 0) {
                    return $parentPath
                }
                else {
                    $parentPath = & $SafeCommands['Split-Path'] -Path $parentPath -Parent
                }
            }
        }
    
        return [string]::Empty
    }
    
    function Get-RelativePath {
        param ( [string] $Path, [string] $RelativeTo )
        return $Path -replace "^$([regex]::Escape("$RelativeTo$([System.IO.Path]::DirectorySeparatorChar)"))?"
    }
    
    function Normalize-Path {
        [CmdletBinding()]
        param (
            [Parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
            [Alias('PSPath', 'FullName')]
            [string[]] $Path
        )
    
        # Split-Path and Join-Path will replace any AltDirectorySeparatorChar instances with the DirectorySeparatorChar
        # (Even if it's not the one that the split / join happens on.)  So splitting / rejoining a path will give us
        # consistent separators for later string comparison.
    
        process {
            if ($null -ne $Path) {
                foreach ($p in $Path) {
                    $normalizedPath = & $SafeCommands['Split-Path'] $p -Leaf
    
                    if ($normalizedPath -ne $p) {
                        $parent = & $SafeCommands['Split-Path'] $p -Parent
                        $normalizedPath = & $SafeCommands['Join-Path'] $parent $normalizedPath
                    }
    
                    $normalizedPath
                }
            }
        }
    }
    
    function Get-JaCoCoReportXml {
        param (
            [parameter(Mandatory = $true)]
            $PesterState,
            [parameter(Mandatory = $true)]
            [object] $CoverageReport
        )
    
        if ($null -eq $CoverageReport -or ($pester.Show -eq [Pester.OutputTypes]::None) -or $CoverageReport.NumberOfCommandsAnalyzed -eq 0) {
            return
        }
    
        $now = & $SafeCommands['Get-Date']
        $nineteenSeventy = & $SafeCommands['Get-Date'] -Date "01/01/1970"
        [long] $endTime = [math]::Floor((New-TimeSpan -start $nineteenSeventy -end $now).TotalMilliseconds)
        [long] $startTime = [math]::Floor($endTime - $PesterState.Time.TotalMilliseconds)
    
        $folderGroups = $PesterState.CommandCoverage | & $SafeCommands["Group-Object"] -Property {
            & $SafeCommands["Split-Path"] $_.File -Parent
        }
    
        $packageList = & $SafeCommands['New-Object'] System.Collections.Generic.List[psobject]
    
        $report = @{
            Instruction = @{ Missed = 0; Covered = 0 }
            Line        = @{ Missed = 0; Covered = 0 }
            Method      = @{ Missed = 0; Covered = 0 }
            Class       = @{ Missed = 0; Covered = 0 }
        }
    
        foreach ($folderGroup in $folderGroups) {
    
            $package = @{
                Name        = $folderGroup.Name
                Classes     = [ordered] @{ }
                Instruction = @{ Missed = 0; Covered = 0 }
                Line        = @{ Missed = 0; Covered = 0 }
                Method      = @{ Missed = 0; Covered = 0 }
                Class       = @{ Missed = 0; Covered = 0 }
            }
    
            foreach ($command in $folderGroup.Group) {
                $file = $command.File
                $function = $command.Function
                if (!$function) { $function = '<script>' }
                $line = $command.StartLine.ToString()
    
                $missed = if ($command.Breakpoint.HitCount) { 0 } else { 1 }
                $covered = if ($command.Breakpoint.HitCount) { 1 } else { 0 }
    
                if (!$package.Classes.Contains($file)) {
                    $package.Class.Missed += $missed
                    $package.Class.Covered += $covered
                    $package.Classes.$file = @{
                        Methods     = [ordered] @{ }
                        Lines       = [ordered] @{ }
                        Instruction = @{ Missed = 0; Covered = 0 }
                        Line        = @{ Missed = 0; Covered = 0 }
                        Method      = @{ Missed = 0; Covered = 0 }
                        Class       = @{ Missed = $missed; Covered = $covered }
                    }
                }
    
                if (!$package.Classes.$file.Methods.Contains($function)) {
                    $package.Method.Missed += $missed
                    $package.Method.Covered += $covered
                    $package.Classes.$file.Method.Missed += $missed
                    $package.Classes.$file.Method.Covered += $covered
                    $package.Classes.$file.Methods.$function = @{
                        FirstLine   = $line
                        Instruction = @{ Missed = 0; Covered = 0 }
                        Line        = @{ Missed = 0; Covered = 0 }
                        Method      = @{ Missed = $missed; Covered = $covered }
                    }
                }
    
                if (!$package.Classes.$file.Lines.Contains($line)) {
                    $package.Line.Missed += $missed
                    $package.Line.Covered += $covered
                    $package.Classes.$file.Line.Missed += $missed
                    $package.Classes.$file.Line.Covered += $covered
                    $package.Classes.$file.Methods.$function.Line.Missed += $missed
                    $package.Classes.$file.Methods.$function.Line.Covered += $covered
                    $package.Classes.$file.Lines.$line = @{
                        Instruction = @{ Missed = 0; Covered = 0 }
                    }
                }
    
                $package.Instruction.Missed += $missed
                $package.Instruction.Covered += $covered
                $package.Classes.$file.Instruction.Missed += $missed
                $package.Classes.$file.Instruction.Covered += $covered
                $package.Classes.$file.Methods.$function.Instruction.Missed += $missed
                $package.Classes.$file.Methods.$function.Instruction.Covered += $covered
                $package.Classes.$file.Lines.$line.Instruction.Missed += $missed
                $package.Classes.$file.Lines.$line.Instruction.Covered += $covered
            }
    
            $report.Class.Missed += $package.Class.Missed
            $report.Class.Covered += $package.Class.Covered
            $report.Method.Missed += $package.Method.Missed
            $report.Method.Covered += $package.Method.Covered
            $report.Line.Missed += $package.Line.Missed
            $report.Line.Covered += $package.Line.Covered
            $report.Instruction.Missed += $package.Instruction.Missed
            $report.Instruction.Covered += $package.Instruction.Covered
    
            $packageList.Add($package)
        }
    
        $commonParent = Get-CommonParentPath -Path $CoverageReport.AnalyzedFiles
        $commonParentLeaf = & $SafeCommands["Split-Path"] $commonParent -Leaf
    
        # the JaCoCo xml format without the doctype, as the XML stuff does not like DTD's.
        $jaCoCoReport = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>'
        $jaCoCoReport += '<report name="">'
        $jaCoCoReport += '<sessioninfo id="this" start="" dump="" />'
        $jaCoCoReport += '</report>'
    
        [xml] $jaCoCoReportXml = $jaCoCoReport
        $reportElement = $jaCoCoReportXml.report
        $reportElement.name = "Pester ($now)"
        $reportElement.sessioninfo.start = $startTime.ToString()
        $reportElement.sessioninfo.dump = $endTime.ToString()
    
        foreach ($package in $packageList) {
            $packageRelativePath = Get-RelativePath -Path $package.Name -RelativeTo $commonParent
    
            if ($null -eq $packageRelativePath) {
                $packageName = $commonParentLeaf
            }
            else {
                $packageName = "{0}/{1}" -f $commonParentLeaf, $($packageRelativePath.Replace("\", "/"))
            }
    
            $packageElement = Add-XmlElement $reportElement "package" @{
                name = ($packageName -replace "/$", "")
            }
    
            foreach ($file in $package.Classes.Keys) {
                $class = $package.Classes.$file
                $classElementRelativePath = (Get-RelativePath -Path $file -RelativeTo $commonParent).Replace("\", "/")
                $classElementName = "{0}/{1}" -f $commonParentLeaf, $classElementRelativePath
                $classElementName = $classElementName.Substring(0, $($classElementName.LastIndexOf(".")))
                $classElement = Add-XmlElement $packageElement 'class' -Attributes ([ordered] @{
                        name           = $classElementName
                        sourcefilename = (& $SafeCommands["Split-Path"] -Path $classElementRelativePath -Leaf)
                    })
    
                foreach ($function in $class.Methods.Keys) {
                    $method = $class.Methods.$function
                    $methodElement = Add-XmlElement $classElement 'method' -Attributes ([ordered] @{
                            name = $function
                            desc = '()'
                            line = $method.FirstLine
                        })
                    Add-JaCoCoCounter Instruction $method $methodElement
                    Add-JaCoCoCounter Line $method $methodElement
                    Add-JaCoCoCounter Method $method $methodElement
                }
    
                Add-JaCoCoCounter Instruction $class $classElement
                Add-JaCoCoCounter Line $class $classElement
                Add-JaCoCoCounter Method $class $classElement
                Add-JaCoCoCounter Class $class $classElement
            }
    
            foreach ($file in $package.Classes.Keys) {
                $class = $package.Classes.$file
                $sourceFileElement = Add-XmlElement $packageElement 'sourcefile' -Attributes ([ordered] @{
                        name = (& $SafeCommands["Split-Path"] -Path $file -Leaf)
                    })
    
                foreach ($line in $class.Lines.Keys) {
                    $null = Add-XmlElement $sourceFileElement 'line' -Attributes ([ordered] @{
                            nr = $line
                            mi = $class.Lines.$line.Instruction.Missed
                            ci = $class.Lines.$line.Instruction.Covered
                        })
                }
    
                Add-JaCoCoCounter Instruction $class $sourceFileElement
                Add-JaCoCoCounter Line $class $sourceFileElement
                Add-JaCoCoCounter Method $class $sourceFileElement
                Add-JaCoCoCounter Class $class $sourceFileElement
            }
    
            Add-JaCoCoCounter Instruction $package $packageElement
            Add-JaCoCoCounter Line $package $packageElement
            Add-JaCoCoCounter Method $package $packageElement
            Add-JaCoCoCounter Class $package $packageElement
        }
    
        Add-JaCoCoCounter Instruction $report $reportElement
        Add-JaCoCoCounter Line $report $reportElement
        Add-JaCoCoCounter Method $report $reportElement
        Add-JaCoCoCounter Class $report $reportElement
    
        # There is no pretty way to insert the Doctype, as microsoft has deprecated the DTD stuff.
        $jaCoCoReportDocType = '<!DOCTYPE report PUBLIC "-//JACOCO//DTD Report 1.1//EN" "report.dtd">'
        return $jaCocoReportXml.OuterXml.Insert(54, $jaCoCoReportDocType)
    }
    
    function Add-XmlElement {
        param (
            [parameter(Mandatory = $true)] [System.Xml.XmlNode] $Parent,
            [parameter(Mandatory = $true)] [string] $Name,
            [System.Collections.IDictionary] $Attributes
        )
        $element = $Parent.AppendChild($Parent.OwnerDocument.CreateElement($Name))
        if ($Attributes) {
            foreach ($key in $Attributes.Keys) {
                $attribute = $element.Attributes.Append($Parent.OwnerDocument.CreateAttribute($key))
                $attribute.Value = $Attributes.$key
            }
        }
        return $element
    }
    
    function Add-JaCoCoCounter {
        param (
            [parameter(Mandatory = $true)] [ValidateSet('Instruction', 'Line', 'Method', 'Class')] [string] $Type,
            [parameter(Mandatory = $true)] [System.Collections.IDictionary] $Data,
            [parameter(Mandatory = $true)] [System.Xml.XmlNode] $Parent
        )
        if ($Data.$Type.Missed -isnot [int] -or $Data.$Type.Covered -isnot [int]) {
            throw 'Counter data expected'
        }
        $null = Add-XmlElement $Parent 'counter' -Attributes ([ordered] @{
                type    = $Type.ToUpperInvariant()
                missed  = $Data.$Type.Missed
                covered = $Data.$Type.Covered
            })
    }
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUQge3lMiLFmU5AA3k49HZr0l+
    # voWggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # W1hJt82Yn1XvZMTZdIAn5g6vF0gwDQYJKoZIhvcNAQEBBQAEggEAl10vfrz2U88U
    # GtaOKMMzJJIz6TsEFvLd61RIqN88nyqN7fDGDdGA+/1XHpWOQ5RRgOEgGlR6fwbv
    # 8usJLUcmFm1bYOsd8MsJaQFS0ccpqG1er9zQrfkjwuHvseEjHcqRr3JcP7zbPibJ
    # yK51mdk4ZphhR1ImKf7reuG3+TEemSpjysG1h/aRFPc1xi0F/7kwXcu10thJvM/H
    # Oi4mGbSXKQkYifM9enTic5mHMGyu6oYOE3h+UiA1hiCTzkOqw06IGS9xmDsUy3sd
    # Kurdq0M+cfhN9SqFjTmzp5G9jq5FUcDvg0yWhMjAie/hIwvbPxjmIs71kZSLez9j
    # rhxvb3gM46GCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzMzWjAjBgkqhkiG9w0BCQQx
    # FgQUtAyleqBU1+7ZwYjOVz8Ng6MokgQwDQYJKoZIhvcNAQEBBQAEggEAJqOpLlKR
    # eZYc6cnjdfozmV5+U1DRLSsWhje4EXVzFLblVfIuLEBi6Km5g6RW4ck03279Ch1q
    # G7VOEzrX9/sP8/+P1uvxg2taWBz5c7nsOfxk7C7r/2h12Q6eCOOJBzEEarvzelw7
    # 2gIdFkuIUHFFMU/OSjvRicdOt4s1QnHIWoAcf+JbB0Mf5GAivAY4Uf8/wojx83Jx
    # I6tFhxNANff+0ORHE2bySnQNlzdgUWBiz45inFBUD6ceivENw+1rPn35j+qtesoS
    # wwsoJcaog+bmenERvng01BwVKVRRECoGvGxy5wWuyxGPV/bwkDKIDSWLONanPO86
    # sGfT7RC+mqJ4Hw==
    # SIG # End signature block
    
  • tools\Functions\Describe.ps1 Show
    function Describe {
        <#
    .SYNOPSIS
    Creates a logical group of tests.
    
    .DESCRIPTION
    Creates a logical group of tests. All Mocks, TestDrive and TestRegistry contents
    defined within a Describe block are scoped to that Describe; they
    will no longer be present when the Describe block exits.  A Describe
    block may contain any number of Context and It blocks.
    
    .PARAMETER Name
    The name of the test group. This is often an expressive phrase describing
    the scenario being tested.
    
    .PARAMETER Fixture
    The actual test script. If you are following the AAA pattern (Arrange-Act-Assert),
    this typically holds the arrange and act sections. The Asserts will also lie
    in this block but are typically nested each in its own It block. Assertions are
    typically performed by the Should command within the It blocks.
    
    .PARAMETER Tag
    Optional parameter containing an array of strings.  When calling Invoke-Pester,
    it is possible to specify a -Tag parameter which will only execute Describe blocks
    containing the same Tag.
    
    .EXAMPLE
    function Add-Numbers($a, $b) {
        return $a + $b
    }
    
    Describe "Add-Numbers" {
        It "adds positive numbers" {
            $sum = Add-Numbers 2 3
            $sum | Should -Be 5
        }
    
        It "adds negative numbers" {
            $sum = Add-Numbers (-2) (-2)
            $sum | Should -Be (-4)
        }
    
        It "adds one negative number to positive number" {
            $sum = Add-Numbers (-2) 2
            $sum | Should -Be 0
        }
    
        It "concatenates strings if given strings" {
            $sum = Add-Numbers two three
            $sum | Should -Be "twothree"
        }
    }
    
    .LINK
    It
    Context
    Invoke-Pester
    about_Should
    about_Mocking
    about_TestDrive
    
    #>
    
        param(
            [Parameter(Mandatory = $true, Position = 0)]
            [string] $Name,
    
            [Alias('Tags')]
            [string[]] $Tag = @(),
    
            [Parameter(Position = 1)]
            [ValidateNotNull()]
            [ScriptBlock] $Fixture
        )
        if ($Fixture -eq $null) {
            if ($Name.Contains("`n")) {
                throw "Test fixture name has multiple lines and no test fixture is provided. (Have you provided a name for the test group?)"
            }
            else {
                throw 'No test fixture is provided. (Have you put the open curly brace on the next line?)'
            }
        }
        if ($null -eq (& $SafeCommands['Get-Variable'] -Name Pester -ValueOnly -ErrorAction $script:IgnoreErrorPreference)) {
            # User has executed a test script directly instead of calling Invoke-Pester
            Remove-MockFunctionsAndAliases
            $sessionState = Set-SessionStateHint -PassThru -Hint "Caller - Captured in Describe" -SessionState $PSCmdlet.SessionState
            $Pester = New-PesterState -Path (& $SafeCommands['Resolve-Path'] .) -TestNameFilter $null -TagFilter @() -SessionState $sessionState
            $script:mockTable = @{}
        }
    
        DescribeImpl @PSBoundParameters -CommandUsed 'Describe' -Pester $Pester -DescribeOutputBlock ${function:Write-Describe} -TestOutputBlock ${function:Write-PesterResult} -NoTestRegistry:('Windows' -ne (GetPesterOs))
    }
    
    function DescribeImpl {
        param(
            [Parameter(Mandatory = $true, Position = 0)]
            [string] $Name,
    
            [Alias('Tags')]
            $Tag = @(),
    
            [Parameter(Position = 1)]
            [ValidateNotNull()]
            [ScriptBlock] $Fixture = $(Throw "No test script block is provided. (Have you put the open curly brace on the next line?)"),
    
            [string] $CommandUsed = 'Describe',
    
            $Pester,
    
            [scriptblock] $DescribeOutputBlock,
    
            [scriptblock] $TestOutputBlock,
    
            [switch] $NoTestDrive,
    
            [switch] $NoTestRegistry
        )
    
        Assert-DescribeInProgress -CommandName $CommandUsed
    
        if (($Pester.RunningViaInvokePester -and $Pester.TestGroupStack.Count -eq 2) -or
            (-not $Pester.RunningViaInvokePester -and $Pester.TestGroupStack.Count -eq 1)) {
            if ($Pester.TestNameFilter -and $Name) {
                if (-not (Contain-AnyStringLike -Filter $Pester.TestNameFilter -Collection $Name)) {
                    return
                }
            }
    
            if ($Pester.ScriptBlockFilter) {
                $match = $false
                foreach ($filter in $Pester.ScriptBlockFilter) {
                    if ($match) {
                        break
                    }
    
                    if ($Fixture.File -eq $filter.Path -and $Fixture.StartPosition.StartLine -eq $filter.Line) {
                        $match = $true
                    }
                }
    
                if (-not $match) {
                    return
                }
            }
    
            if ($Pester.TagFilter) {
                if (-not (Contain-AnyStringLike -Filter $Pester.TagFilter -Collection $Tag)) {
                    return
                }
            }
    
            if ($Pester.ExcludeTagFilter) {
                if (Contain-AnyStringLike -Filter $Pester.ExcludeTagFilter -Collection $Tag) {
                    return
                }
            }
        }
        else {
            if ($PSBoundParameters.ContainsKey('Tag')) {
                Write-Warning "${CommandUsed} '$Name': Tags are only effective on the outermost test group, for now."
            }
        }
    
        $Pester.EnterTestGroup($Name, $CommandUsed)
    
        if ($null -ne $DescribeOutputBlock) {
            & $DescribeOutputBlock $Name $CommandUsed
        }
    
        $testDriveAdded = $false
        $testRegistryAdded = $false
        try {
            try {
                if (-not $NoTestDrive) {
                    if (-not (Test-Path TestDrive:\)) {
                        New-TestDrive
                        $testDriveAdded = $true
                    }
                    else {
                        $TestDriveContent = Get-TestDriveChildItem
                    }
                }
    
                if (-not $NoTestRegistry) {
                    if (-not (Test-Path TestRegistry:\)) {
                        New-TestRegistry
                        $testRegistryAdded = $true
                    }
                    else {
                        $TestRegistryContent = Get-TestRegistryChildItem
                    }
                }
    
                Add-SetupAndTeardown -ScriptBlock $Fixture
                Invoke-TestGroupSetupBlocks
    
                do {
                    Write-ScriptBlockInvocationHint -Hint "Describe Fixture" -ScriptBlock $Fixture
                    $null = & $Fixture
                } until ($true)
            }
            finally {
                Invoke-TestGroupTeardownBlocks
    
                if (-not $NoTestDrive) {
                    if ($testDriveAdded) {
                        Remove-TestDrive
                    }
                    else {
                        Clear-TestDrive -Exclude ($TestDriveContent | & $SafeCommands['Select-Object'] -ExpandProperty FullName)
                    }
                }
    
                if (-not $NoTestRegistry) {
                    if ($testRegistryAdded) {
                        Remove-TestRegistry
                    }
                    else {
                        Clear-TestRegistry -Exclude ($TestRegistryContent | & $SafeCommands['Select-Object'] -ExpandProperty PSPath)
                    }
                }
            }
        }
        catch {
            $firstStackTraceLine = $_.InvocationInfo.PositionMessage.Trim() -split "$([System.Environment]::NewLine)" | & $SafeCommands['Select-Object'] -First 1
            $Pester.AddTestResult("Error occurred in $CommandUsed block", "Failed", $null, $_.Exception.Message, $firstStackTraceLine, $null, $null, $_)
            if ($null -ne $TestOutputBlock) {
                & $TestOutputBlock $Pester.TestResult[-1]
            }
        }
    
        Exit-MockScope
    
        $Pester.LeaveTestGroup($Name, $CommandUsed)
    }
    
    # Name is now misleading; rename later.  (Many files touched to change this.)
    function Assert-DescribeInProgress {
        param ($CommandName)
        if ($null -eq $Pester) {
            throw "The $CommandName command may only be used from a Pester test script."
        }
    }
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUUdaUxF7d79fCJXbv7GdAAxGB
    # DhKggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # XgkHI2V1mSofM1zjgFK5aYe88TcwDQYJKoZIhvcNAQEBBQAEggEATBeZjqd6oFR9
    # EkWS0vrv3JBQ80CHqYBGWAGjhpDhROo0/g/W8Jki50y8nD8XQlLaXVZD0kcT3a75
    # JzmA+s1+bVBa73U0dHrfVBla9XzJHDKGMlMJrK7vHvIoOwiiBBW1ioYgjalbtAiD
    # YI78jW+UC1MRrpNH7qfXoJ9FchPoiXe37KheYGQFBDSTPUPyxxPDW+UVpL4N+KbK
    # OfeU1xA4613NlZ/cmJo+EfR2zFJ0Lwo0+7clMw9mUJ5IIrMBRLO2rN/29p74J9lh
    # ZxJUJGK4fytZfv5IZD5/ittTaPtUe2ZlknjRTNxiHQTcnCvruihLSzLS/pKdCJbN
    # expErpjYDqGCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzM1WjAjBgkqhkiG9w0BCQQx
    # FgQUUWgWwRfz5YofYAgNRaSI3V4KTdIwDQYJKoZIhvcNAQEBBQAEggEAQKb48pd7
    # 1pRt6jD5XktTqpn7yQ7A5VcIDkkjHSsR4R75RJGex7KPp+uIiItfdVjt/o0ktXEN
    # T7FpEM8TRvL6jz8lI+yWDX7Dh17N/+oKpuxj3EVMVsFXwg4bMG9r6jZI3TwBsA0X
    # cEODUOv+UuGasSTDWcxulPVdeCtF7LeAgG8N3C2pswDNby4Vjco01BYJ6NvfsTxp
    # YfkVXewDtOLT7GcdOp90nNW0FU94fOm4NmjVDWj80ouDp+AfTmw99eZliIGMSpr4
    # kAuP9XibipJ811VFMKq2H8JsJw59uzbo3INvyHnmfH6IrgZy2dwrGewfdWWsh4an
    # roCnv27fj38PrQ==
    # SIG # End signature block
    
  • tools\Functions\Environment.ps1 Show
    function GetPesterPsVersion {
        # accessing the value indirectly so it can be mocked
        (Get-Variable 'PSVersionTable' -ValueOnly).PSVersion.Major
    }
    
    function GetPesterOs {
        # Prior to v6, PowerShell was solely on Windows. In v6, the $IsWindows variable was introduced.
        if ((GetPesterPsVersion) -lt 6) {
            'Windows'
        }
        elseif (Get-Variable -Name 'IsWindows' -ErrorAction 'SilentlyContinue' -ValueOnly ) {
            'Windows'
        }
        elseif (Get-Variable -Name 'IsMacOS' -ErrorAction 'SilentlyContinue' -ValueOnly ) {
            'macOS'
        }
        elseif (Get-Variable -Name 'IsLinux' -ErrorAction 'SilentlyContinue' -ValueOnly ) {
            'Linux'
        }
        else {
            throw "Unsupported Operating system!"
        }
    }
    
    function Get-TempDirectory {
        if ((GetPesterOs) -eq 'Windows') {
            $env:TEMP
        }
        else {
            '/tmp'
        }
    }
    
    function Get-TempRegistry {
        $pesterTempRegistryRoot = 'Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\Pester'
        if (-not (Test-Path $pesterTempRegistryRoot)) {
            try {
                $null = New-Item -Path $pesterTempRegistryRoot -ErrorAction Stop
            }
            catch [Exception] {
                throw (New-Object Exception -ArgumentList "Was not able to create a Pester Registry key for TestRegistry", ($_.Exception))
            }
        }
        return $pesterTempRegistryRoot
    }
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQU/505oUEiBJ8ifox7rTGb9x7T
    # f8qggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # 5GVU7KB6PKJ+u3WXHQKtT+YP3TQwDQYJKoZIhvcNAQEBBQAEggEAn47FAw/foVq3
    # a2Slcq415JHg03jDCOTXPUMK2mCWISr12iAa9p+XklIU1IKv9PQ30mGhQ35HtM9T
    # LRCiLYhTiwM7jraomVlwrIjdcDCW6RyfPyosawOGeswgtLKKCXw6TgKbljVr70il
    # zF7QiK1WUh58EZ9U1ZAbTQe3XEItDtUGhsSuq9tnGz4X4Imdg7eJg4Zj0od5Qo2v
    # 0Fa3dsuzz3Lmcjwxpt/cwcVAJTOzQfB+n9tAgmDJ3lCg/oRUgYsH3ZrAUru3TIFT
    # OgvlhijNfb69Vek8Ta2GJ9cUVahNO/OXoj7y95iMk1em1I172XygGXys8c1tGw47
    # t6vImxIsQKGCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzM1WjAjBgkqhkiG9w0BCQQx
    # FgQUi52PuXEuspmcQ6QWshlC4i2APfYwDQYJKoZIhvcNAQEBBQAEggEAZpv1ShnU
    # ApmNBe2wytDNKTm4GO0jhizAHobbyK6XH51LD6k/F7h6sfvba/UMLhRQoe3wpF1o
    # 7psV46XZVZtnCXuaTmkguEPfJS22sGc+ZJXH0yM/rAZ1bXlTckbXQ83Xl/JFgQHW
    # v64Phd9M9Nt0/AAgQ755iEyA82ZUOAa3m5gp4C0r9f+kABFgwmtWOemksWWm0VXY
    # kTprbtjmoO0eUVSKvOqK6e4b3xjzRvgU1dOsRTwN/ttlOEA6P18zxGwR0JgB33uX
    # 324XWyRB+UBY0TyunsKqZq8lVKS5y3o5JLX4mkREY0YOGrRtBVw1Ozs5v11lhK1j
    # bWNoLODRTiJFUA==
    # SIG # End signature block
    
  • tools\Functions\Get-ShouldOperator.ps1 Show
    function Get-ShouldOperator {
        <#
        .SYNOPSIS
        Display the assertion operators available for use with Should.
    
        .DESCRIPTION
        Get-ShouldOperator returns a list of available Should parameters,
        their aliases, and examples to help you craft the tests you need.
    
        Get-ShouldOperator will list all available operators,
        including any registered by the user with Add-AssertionOperator.
    
        .NOTES
        Pester uses dynamic parameters to populate Should arguments.
    
        This limits the user's ability to discover the available assertions via
        standard PowerShell discovery patterns (like `Get-Help Should -Parameter *`).
    
        .EXAMPLE
        Get-ShouldOperator
        Return all available Should assertion operators and their aliases.
    
        .EXAMPLE
        Get-ShouldOperator -Name Be
        Return help examples for the Be assertion operator.
        -Name is a dynamic parameter that tab completes all available options.
    
        .LINK
        https://github.com/Pester/Pester
        about_Should
        #>
        [CmdletBinding()]
        param ()
    
        # Use a dynamic parameter to create a dynamic ValidateSet
        # Define parameter -Name and tab-complete all current values of $AssertionOperators
        # Discovers included assertions (-Be, -Not) and any registered by the user via Add-AssertionOperator
        # https://martin77s.wordpress.com/2014/06/09/dynamic-validateset-in-a-dynamic-parameter/
        DynamicParam {
            $ParameterName = 'Name'
    
            $RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
            $AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
            $ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute
    
            $AttributeCollection.Add($ParameterAttribute)
    
            $arrSet = $AssertionOperators.Values |
                Select-Object -Property Name, Alias |
                ForEach-Object { $_.Name; $_.Alias }
    
            $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($arrSet)
    
            $AttributeCollection.Add($ValidateSetAttribute)
    
            $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName, [string], $AttributeCollection)
            $RuntimeParameterDictionary.Add($ParameterName, $RuntimeParameter)
            return $RuntimeParameterDictionary
        }
    
        BEGIN {
            # Bind the parameter to a friendly variable
            $Name = $PsBoundParameters[$ParameterName]
        }
    
        END {
            if ($Name) {
                $operator = $AssertionOperators.Values | Where-Object { $Name -eq $_.Name -or $_.Alias -contains $Name }
                $help = Get-Help $operator.InternalName -Examples -ErrorAction SilentlyContinue
    
                if (($help | Measure-Object).Count -ne 1) {
                    Write-Warning ("No help found for Should operator '{0}'" -f ((Get-AssertionOperatorEntry $Name).InternalName))
                }
                else {
                    $help
                }
            }
            else {
                $AssertionOperators.Keys | ForEach-Object {
                    $aliases = (Get-AssertionOperatorEntry $_).Alias
    
                    # Return name and alias(es) for all registered Should operators
                    New-Object -TypeName PSObject -Property @{
                        Name  = $_
                        Alias = $aliases -join ', '
                    }
                }
            }
        }
    }
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQU3lya7+3AWNPbsRuVCBWC8Dry
    # DbmggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # qv8snwM3Rb/KLTktdM3AVbRaYF8wDQYJKoZIhvcNAQEBBQAEggEAAZ1joANW1n6O
    # pTVPaOuIG1eEapUu5RgXYMcx/PscL4HxgU4uTGEgJghqhY/lZ9ItPq6n9MG8kmV8
    # 6qpj2riF8aL9zx/0eCS2x20jftYzk6ynBoWI704oGvq1UvBx6Flfevv8PND9/pov
    # oeyT8PRL/go4H28qqgdBLUuuGQruuSiUWVgy6jlpjufR3N7XTp/raNCX3trGSnRc
    # M/mYS+z6ZZ+HjZutcN44RtoRW742t5l+wPKvYG/0O+FcqyFQk677isgIupcfESTJ
    # 8rTlX+sxoB5ESzmdqKbXGVeSPyqwGsR3fpAhGMv9imgbMXTrNIKlxCSJL8ysx7iy
    # krils6Tn2KGCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzM2WjAjBgkqhkiG9w0BCQQx
    # FgQUV+L81/ewhyy2VtX54txhYpDmwvIwDQYJKoZIhvcNAQEBBQAEggEABvm7yA8n
    # Nu4yd12Y33B/oVJQsFJepPXuSuYHtFQEUjauXq8du1CkXLcIGYB0+mURhlvUNuuH
    # k2x9P7T8CzhvCintsDAcmbu7/0JdsWeGnRZTITem5LoNFedJoJX686NG+/1+sOs4
    # dLfFP3UfLnpR56dyu7lPrFIdx0D3VoPL5HItnMVxKwgE+gJLV086N89mtr8pKLku
    # dFo46Nu5mYMm9z+URwb4tjXqRDPxvsS2IHxvmUunG4SqaWAikcsEU+4srLqzyTZf
    # XF5kVTq/ji0qvCtofipuT5059uXi5fHkczgwjbgxNwXzF97ENb1e5NoC47uaoXGT
    # sy0bjvFv7psX2A==
    # SIG # End signature block
    
  • tools\Functions\Gherkin.ps1 Show
    if (($PSVersionTable.ContainsKey('PSEdition')) -and ($PSVersionTable.PSEdition -eq 'Core')) {
        & $SafeCommands["Add-Type"] -Path "${Script:PesterRoot}/lib/Gherkin/core/Gherkin.dll"
    }
    else {
        & $SafeCommands["Import-Module"] -Name "${Script:PesterRoot}/lib/Gherkin/legacy/Gherkin.dll"
    }
    
    $GherkinSteps = @{}
    $GherkinHooks = @{
        BeforeEachFeature  = @()
        BeforeEachScenario = @()
        AfterEachFeature   = @()
        AfterEachScenario  = @()
    }
    
    function Invoke-GherkinHook {
        <#
            .SYNOPSIS
                Internal function to run the various gherkin hooks
    
            .PARAMETER Hook
                The name of the hook to run
    
            .PARAMETER Name
                The name of the feature or scenario the hook is being invoked for
    
            .PARAMETER Tags
                Tags for filtering hooks
        #>
        [CmdletBinding()]
        param([string]$Hook, [string]$Name, [string[]]$Tags)
    
        if ($GherkinHooks.${Hook}) {
            foreach ($GherkinHook in $GherkinHooks.${Hook}) {
                if ($GherkinHook.Tags -and $Tags) {
                    :tags foreach ($hookTag in $GherkinHook.Tags) {
                        foreach ($testTag in $Tags) {
                            if ($testTag -match "^($hookTag)$") {
                                & $hook.Script $Name
                                break :tags
                            }
                        }
                    }
                }
                elseif ($GherkinHook.Tags) {
                    # If the hook has tags, it can't run if the step doesn't
                }
                else {
                    & $GherkinHook.Script $Name
                }
            } # @{ Tags = $Tags; Script = $Test }
        }
    }
    
    function Invoke-Gherkin {
        <#
            .SYNOPSIS
                Invokes Pester to run all tests defined in .feature files
    
            .DESCRIPTION
                Upon calling Invoke-Gherkin, all files that have a name matching *.feature in the current folder (and child folders recursively), will be parsed and executed.
    
                If ScenarioName is specified, only scenarios which match the provided name(s) will be run.
                If FailedLast is specified, only scenarios which failed the previous run will be re-executed.
    
                Optionally, Pester can generate a report of how much code is covered by the tests, and information about any commands which were not executed.
            .PARAMETER FailedLast
                Rerun only the scenarios which failed last time
            .PARAMETER Path
                This parameter indicates which feature files should be tested.
    
                Aliased to 'Script' for compatibility with Pester, but does not support hashtables, since feature files don't take parameters.
    
            .PARAMETER ScenarioName
                When set, invokes testing of scenarios which match this name.
    
                Aliased to 'Name' and 'TestName' for compatibility with Pester.
    
            .PARAMETER EnableExit
                Will cause Invoke-Gherkin to exit with a exit code equal to the number of failed tests once all tests have been run.
                Use this to "fail" a build when any tests fail.
    
            .PARAMETER Tag
                Filters Scenarios and Features and runs only the ones tagged with the specified tags.
    
            .PARAMETER ExcludeTag
                Informs Invoke-Gherkin to not run blocks tagged with the tags specified.
    
            .PARAMETER CodeCoverage
                Instructs Pester to generate a code coverage report in addition to running tests.  You may pass either hashtables or strings to this parameter.
    
                If strings are used, they must be paths (wildcards allowed) to source files, and all commands in the files are analyzed for code coverage.
    
                By passing hashtables instead, you can limit the analysis to specific lines or functions within a file.
                Hashtables must contain a Path key (which can be abbreviated to just "P"), and may contain Function (or "F"), StartLine (or "S"),
                and EndLine ("E") keys to narrow down the commands to be analyzed.
                If Function is specified, StartLine and EndLine are ignored.
    
                If only StartLine is defined, the entire script file starting with StartLine is analyzed.
                If only EndLine is present, all lines in the script file up to and including EndLine are analyzed.
    
                Both Function and Path (as well as simple strings passed instead of hashtables) may contain wildcards.
    
            .PARAMETER Strict
                Makes Pending and Skipped tests to Failed tests. Useful for continuous integration where you need
                to make sure all tests passed.
    
            .PARAMETER OutputFile
                The path to write a report file to. If this path is not provided, no log will be generated.
    
            .PARAMETER OutputFormat
                The format for output (LegacyNUnitXml or NUnitXml), defaults to NUnitXml
    
            .PARAMETER Quiet
                Disables the output Pester writes to screen. No other output is generated unless you specify PassThru,
                or one of the Output parameters.
    
            .PARAMETER PesterOption
                Sets advanced options for the test execution. Enter a PesterOption object,
                such as one that you create by using the New-PesterOption cmdlet, or a hash table
                in which the keys are option names and the values are option values.
                For more information on the options available, see the help for New-PesterOption.
    
            .PARAMETER Show
                Customizes the output Pester writes to the screen. Available options are None, Default,
                Passed, Failed, Pending, Skipped, Inconclusive, Describe, Context, Summary, Header, All, Fails.
    
                The options can be combined to define presets.
                Common use cases are:
    
                None - to write no output to the screen.
                All - to write all available information (this is default option).
                Fails - to write everything except Passed (but including Describes etc.).
    
                A common setting is also Failed, Summary, to write only failed tests and test summary.
    
                This parameter does not affect the PassThru custom object or the XML output that
                is written when you use the Output parameters.
    
            .PARAMETER PassThru
                Returns a custom object (PSCustomObject) that contains the test results.
                By default, Invoke-Gherkin writes to the host program, not to the output stream (stdout).
                If you try to save the result in a variable, the variable is empty unless you
                use the PassThru parameter.
                To suppress the host output, use the Quiet parameter.
    
            .EXAMPLE
                Invoke-Gherkin
    
                This will find all *.feature specifications and execute their tests. No exit code will be returned and no log file will be saved.
    
            .EXAMPLE
                Invoke-Gherkin -Path ./tests/Utils*
    
                This will run all *.feature specifications under ./Tests that begin with Utils.
    
            .EXAMPLE
                Invoke-Gherkin -ScenarioName "Add Numbers"
    
                This will only run the Scenario named "Add Numbers"
    
            .EXAMPLE
                Invoke-Gherkin -EnableExit -OutputXml "./artifacts/TestResults.xml"
    
                This runs all tests from the current directory downwards and writes the results according to the NUnit schema to artifacts/TestResults.xml just below the current directory. The test run will return an exit code equal to the number of test failures.
    
            .EXAMPLE
                Invoke-Gherkin -CodeCoverage 'ScriptUnderTest.ps1'
    
                Runs all *.feature specifications in the current directory, and generates a coverage report for all commands in the "ScriptUnderTest.ps1" file.
    
            .EXAMPLE
                Invoke-Gherkin -CodeCoverage @{ Path = 'ScriptUnderTest.ps1'; Function = 'FunctionUnderTest' }
    
                Runs all *.feature specifications in the current directory, and generates a coverage report for all commands in the "FunctionUnderTest" function in the "ScriptUnderTest.ps1" file.
    
            .EXAMPLE
                Invoke-Gherkin -CodeCoverage @{ Path = 'ScriptUnderTest.ps1'; StartLine = 10; EndLine = 20 }
    
                Runs all *.feature specifications in the current directory, and generates a coverage report for all commands on lines 10 through 20 in the "ScriptUnderTest.ps1" file.
    
            .LINK
                Invoke-Pester
                https://kevinmarquette.github.io/2017-03-17-Powershell-Gherkin-specification-validation/
                https://kevinmarquette.github.io/2017-04-30-Powershell-Gherkin-advanced-features/
        #>
        [CmdletBinding(DefaultParameterSetName = 'Default')]
        param(
            [Parameter(Mandatory = $True, ParameterSetName = "RetestFailed")]
            [switch]$FailedLast,
    
            [Parameter(Position = 0, Mandatory = $False)]
            [Alias('Script', 'relative_path')]
            [string]$Path = $Pwd,
    
            [Parameter(Position = 1, Mandatory = $False)]
            [Alias("Name", "TestName")]
            [string[]]$ScenarioName,
    
            [Parameter(Position = 2, Mandatory = $False)]
            [switch]$EnableExit,
    
            [Parameter(Position = 4, Mandatory = $False)]
            [Alias('Tags')]
            [string[]]$Tag,
    
            [string[]]$ExcludeTag,
    
            [object[]] $CodeCoverage = @(),
    
            [Switch]$Strict,
    
            [string] $OutputFile,
    
            [ValidateSet('NUnitXml')]
            [string] $OutputFormat = 'NUnitXml',
    
            [Switch]$Quiet,
    
            [object]$PesterOption,
    
            [Pester.OutputTypes]$Show = 'All',
    
            [switch]$PassThru
        )
        begin {
            & $SafeCommands["Import-LocalizedData"] -BindingVariable Script:ReportStrings -BaseDirectory $PesterRoot -FileName Gherkin.psd1 -ErrorAction SilentlyContinue
    
            #Fallback to en-US culture strings
            If ([String]::IsNullOrEmpty($ReportStrings)) {
    
                & $SafeCommands["Import-LocalizedData"] -BaseDirectory $PesterRoot -BindingVariable Script:ReportStrings -UICulture 'en-US' -FileName Gherkin.psd1 -ErrorAction Stop
    
            }
    
            # Make sure broken tests don't leave you in space:
            $CWD = [Environment]::CurrentDirectory
            $Location = & $SafeCommands["Get-Location"]
            [Environment]::CurrentDirectory = & $SafeCommands["Get-Location"] -PSProvider FileSystem
    
            $script:GherkinSteps = @{}
            $script:GherkinHooks = @{
                BeforeEachFeature  = @()
                BeforeEachScenario = @()
                AfterEachFeature   = @()
                AfterEachScenario  = @()
            }
        }
        end {
            if ($PSBoundParameters.ContainsKey('Quiet')) {
                & $SafeCommands["Write-Warning"] 'The -Quiet parameter has been deprecated; please use the new -Show parameter instead. To get no output use -Show None.'
                & $SafeCommands["Start-Sleep"] -Seconds 2
    
                if (!$PSBoundParameters.ContainsKey('Show')) {
                    $Show = [Pester.OutputTypes]::None
                }
            }
    
            if ($PSCmdlet.ParameterSetName -eq "RetestFailed" -and $FailedLast) {
                $ScenarioName = $script:GherkinFailedLast
                if (!$ScenarioName) {
                    throw "There are no existing failed tests to re-run."
                }
            }
            $sessionState = Set-SessionStateHint -PassThru  -Hint "Caller - Captured in Invoke-Gherkin" -SessionState $PSCmdlet.SessionState
            $pester = New-PesterState -TagFilter $Tag -ExcludeTagFilter $ExcludeTag -TestNameFilter $ScenarioName -SessionState $sessionState -Strict:$Strict  -Show $Show -PesterOption $PesterOption |
                & $SafeCommands["Add-Member"] -MemberType NoteProperty -Name Features -Value (& $SafeCommands["New-Object"] System.Collections.Generic.List[PSObject] ) -PassThru |
                & $SafeCommands["Add-Member"] -MemberType ScriptProperty -Name FailedScenarios -PassThru -Value {
                $Names = $this.TestResult | & $SafeCommands["Group-Object"] Describe |
                    & $SafeCommands["Where-Object"] { $_.Group |
                        & $SafeCommands["Where-Object"] { -not $_.Passed } } |
                    & $SafeCommands["Select-Object"] -ExpandProperty Name
                $this.Features | Select-Object -ExpandProperty Scenarios | & $SafeCommands["Where-Object"] { $Names -contains $_.Name }
            } |
                & $SafeCommands["Add-Member"] -MemberType ScriptProperty -Name PassedScenarios -PassThru -Value {
                $Names = $this.TestResult | & $SafeCommands["Group-Object"] Describe |
                    & $SafeCommands["Where-Object"] { -not ($_.Group |
                            & $SafeCommands["Where-Object"] { -not $_.Passed }) } |
                    & $SafeCommands["Select-Object"] -ExpandProperty Name
                $this.Features | Select-Object -ExpandProperty Scenarios | & $SafeCommands["Where-Object"] { $Names -contains $_.Name }
            }
    
            Write-PesterStart $pester $Path
    
            Enter-CoverageAnalysis -CodeCoverage $CodeCoverage -PesterState $pester
    
            foreach ($FeatureFile in & $SafeCommands["Get-ChildItem"] $Path -Filter "*.feature" -Recurse ) {
                Invoke-GherkinFeature $FeatureFile -Pester $pester
            }
    
            # Remove all the steps
            $Script:GherkinSteps.Clear()
    
            $Location | & $SafeCommands["Set-Location"]
            [Environment]::CurrentDirectory = $CWD
    
            $pester | Write-PesterReport
            $coverageReport = Get-CoverageReport -PesterState $pester
            Write-CoverageReport -CoverageReport $coverageReport
            Exit-CoverageAnalysis -PesterState $pester
    
            if (& $SafeCommands["Get-Variable"]-Name OutputFile -ValueOnly -ErrorAction $script:IgnoreErrorPreference) {
                Export-PesterResults -PesterState $pester -Path $OutputFile -Format $OutputFormat
            }
    
            if ($PassThru) {
                # Remove all runtime properties like current* and Scope
                $properties = @(
                    "Path", "Features", "TagFilter", "TestNameFilter", "TotalCount", "PassedCount", "FailedCount", "Time", "TestResult", "PassedScenarios", "FailedScenarios"
    
                    if ($CodeCoverage) {
                        @{ Name = 'CodeCoverage'; Expression = { $coverageReport } }
                    }
                )
                $result = $pester | & $SafeCommands["Select-Object"] -Property $properties
                $result.PSTypeNames.Insert(0, "Pester.Gherkin.Results")
                $result
            }
            $script:GherkinFailedLast = @($pester.FailedScenarios.Name)
            if ($EnableExit) {
                Exit-WithCode -FailedCount $pester.FailedCount
            }
        }
    }
    
    function Import-GherkinSteps {
        <#
            .SYNOPSIS
                Internal function for importing the script steps from a directory tree
            .PARAMETER StepPath
                The folder which contains step files
            .PARAMETER Pester
                Pester
        #>
    
        [CmdletBinding()]
        param(
    
            [Alias("PSPath")]
            [Parameter(Mandatory = $True, Position = 0, ValueFromPipelineByPropertyName = $True)]
            $StepPath,
    
            [PSObject]$Pester
        )
        begin {
            # Remove all existing steps
            $Script:GherkinSteps.Clear()
            # Remove all existing hooks
            $Script:GherkinHooks.Clear()
        }
        process {
            $StepFiles = & $SafeCommands["Get-ChildItem"] $StepPath -Filter "*.?teps.ps1" -Include "*.[sS]teps.ps1" -Recurse
    
            foreach ($StepFile in $StepFiles) {
                $invokeTestScript = {
                    [CmdletBinding()]
                    param (
                        [Parameter(Position = 0)]
                        [string] $Path
                    )
    
                    & $Path
                }
    
                Set-ScriptBlockScope -ScriptBlock $invokeTestScript -SessionState $Pester.SessionState
    
                & $invokeTestScript $StepFile.FullName
            }
    
            & $SafeCommands["Write-Verbose"] "Loaded $($Script:GherkinSteps.Count) step definitions from $(@($StepFiles).Count) steps file(s)"
        }
    }
    
    function Import-GherkinFeature {
        <#
            .SYNOPSIS
                Internal function to import a Gherkin feature file. Wraps Gherkin.Parse
    
            .PARAMETER Path
                The path to the feature file to import
    
            .PARAMETER Pester
                Internal Pester object. For internal use only
        #>
        [CmdletBinding()]
        param($Path, [PSObject]$Pester)
        $Background = $null
    
        $parser = & $SafeCommands["New-Object"] Gherkin.Parser
        $Feature = $parser.Parse($Path).Feature | Convert-Tags
        $Scenarios = $(
            :scenarios foreach ($Child in $Feature.Children) {
                $null = & $SafeCommands["Add-Member"] -MemberType "NoteProperty" -InputObject $Child.Location -Name "Path" -Value $Path
                foreach ($Step in $Child.Steps) {
                    $null = & $SafeCommands["Add-Member"] -MemberType "NoteProperty" -InputObject $Step.Location -Name "Path" -Value $Path
                }
    
                switch ($Child.Keyword.Trim()) {
                    { (Test-Keyword $_ 'scenario' $Feature.Language) -or (Test-Keyword $_ 'scenarioOutline' $Feature.Language) } {
                        $Scenario = Convert-Tags -InputObject $Child -BaseTags $Feature.Tags
                    }
                    { Test-Keyword $_ 'background' $Feature.Language } {
                        $Background = Convert-Tags -InputObject $Child -BaseTags $Feature.Tags
                        continue scenarios
                    }
                    default {
                        & $SafeCommands["Write-Warning"] "Unexpected Feature Child: $_"
                    }
                }
    
                if ( $Scenario -is [Gherkin.Ast.ScenarioOutline] ) {
                    # If there is no example set name, the following index will be included in the scenario name
                    $ScenarioIndex = 0
                    foreach ($ExampleSet in $Scenario.Examples) {
                        ${Column Names} = @($ExampleSet.TableHeader.Cells | & $SafeCommands["Select-Object"] -ExpandProperty Value)
                        $NamesPattern = "<(?:" + (${Column Names} -join "|") + ")>"
                        # If there is an example set name, the following index will be included in the scenario name
                        $ExampleSetIndex = 0
                        foreach ($Example in $ExampleSet.TableBody) {
                            $ScenarioIndex++
                            $ExampleSetIndex++
                            $Steps = foreach ($Step in $Scenario.Steps) {
                                [string]$StepText = $Step.Text
                                if ($StepText -match $NamesPattern) {
                                    for ($n = 0; $n -lt ${Column Names}.Length; $n++) {
                                        $Name = ${Column Names}[$n]
                                        if ($Example.Cells[$n].Value -and $StepText -match "<${Name}>") {
                                            $StepText = $StepText -replace "<${Name}>", $Example.Cells[$n].Value
                                        }
                                    }
                                }
                                if ($StepText -ne $Step.Text) {
                                    & $SafeCommands["New-Object"] Gherkin.Ast.Step $Step.Location, $Step.Keyword.Trim(), $StepText, $Step.Argument
                                }
                                else {
                                    $Step
                                }
                            }
                            $ScenarioName = $Scenario.Name
                            if ($ExampleSet.Name) {
                                # Include example set name and index of example
                                $ScenarioName = $ScenarioName + " [$($ExampleSet.Name.Trim()) $ExampleSetIndex]"
                            }
                            else {
                                # Only include index of scenario
                                $ScenarioName = $ScenarioName + " [$ScenarioIndex]"
                            }
                            & $SafeCommands["New-Object"] Gherkin.Ast.Scenario $ExampleSet.Tags, $Scenario.Location, $Scenario.Keyword.Trim(), $ScenarioName, $Scenario.Description, $Steps | Convert-Tags $Scenario.Tags
                        }
                    }
                }
                else {
                    $Scenario
                }
            }
        )
    
        & $SafeCommands["Add-Member"] -MemberType NoteProperty -InputObject $Feature -Name Scenarios -Value $Scenarios -Force
        return $Feature, $Background, $Scenarios
    }
    
    function Invoke-GherkinFeature {
        <#
            .SYNOPSIS
                Internal function to (parse and) run a whole feature file
        #>
        [CmdletBinding()]
        param(
            [Alias("PSPath")]
            [Parameter(Mandatory = $True, Position = 0, ValueFromPipelineByPropertyName = $True)]
            [IO.FileInfo]$FeatureFile,
    
            [PSObject]$Pester
        )
        # Make sure broken tests don't leave you in space:
        $CWD = [Environment]::CurrentDirectory
        $Location = & $SafeCommands["Get-Location"]
        [Environment]::CurrentDirectory = & $SafeCommands["Get-Location"] -PSProvider FileSystem
    
        try {
            $Parent = & $SafeCommands["Split-Path"] $FeatureFile.FullName
            Import-GherkinSteps -StepPath $Parent -Pester $pester
            $Feature, $Background, $Scenarios = Import-GherkinFeature -Path $FeatureFile.FullName -Pester $Pester
        }
        catch [Gherkin.ParserException] {
            & $SafeCommands["Write-Error"] -Exception $_.Exception -Message "Skipped '$($FeatureFile.FullName)' because of parser error.`n$(($_.Exception.Errors | & $SafeCommands["Select-Object"] -Expand Message) -join "`n`n")"
            continue
        }
    
        # To create a more user-friendly test report, we use the feature name for the test group
        $Pester.EnterTestGroup($Feature.Name, 'Script')
    
        $null = $Pester.Features.Add($Feature)
        Invoke-GherkinHook BeforeEachFeature $Feature.Name $Feature.Tags
    
        # Test the name filter first, since it will probably return one single item
        if ($Pester.TestNameFilter) {
            $Scenarios = foreach ($nameFilter in $Pester.TestNameFilter) {
                $Scenarios | & $SafeCommands["Where-Object"] { $_.Name -like $NameFilter }
            }
            $Scenarios = $Scenarios | & $SafeCommands["Get-Unique"]
        }
    
        # if($Pester.TagFilter -and @(Compare-Object $Tags $Pester.TagFilter -IncludeEqual -ExcludeDifferent).count -eq 0) {return}
        if ($Pester.TagFilter) {
            $Scenarios = $Scenarios | & $SafeCommands["Where-Object"] { & $SafeCommands["Compare-Object"] $_.Tags $Pester.TagFilter -IncludeEqual -ExcludeDifferent }
        }
    
        # if($Pester.ExcludeTagFilter -and @(Compare-Object $Tags $Pester.ExcludeTagFilter -IncludeEqual -ExcludeDifferent).count -gt 0) {return}
        if ($Pester.ExcludeTagFilter) {
            $Scenarios = $Scenarios | & $SafeCommands["Where-Object"] { !(& $SafeCommands["Compare-Object"] $_.Tags $Pester.ExcludeTagFilter -IncludeEqual -ExcludeDifferent) }
        }
    
        if ($Scenarios) {
            Write-Describe (New-Object PSObject -Property @{Name = "$($Feature.Keyword): $($Feature.Name)"; Description = $Feature.Description })
        }
    
        try {
            foreach ($Scenario in $Scenarios) {
                Invoke-GherkinScenario $Pester $Scenario $Background $Feature.Language
            }
        }
        catch {
            $firstStackTraceLine = $_.ScriptStackTrace -split '\r?\n' | & $SafeCommands["Select-Object"] -First 1
            $Pester.AddTestResult("Error occurred in test script '$($Feature.Path)'", "Failed", $null, $_.Exception.Message, $firstStackTraceLine, $null, $null, $_)
    
            # This is a hack to ensure that XML output is valid for now.  The test-suite names come from the Describe attribute of the TestResult
            # objects, and a blank name is invalid NUnit XML.  This will go away when we promote test scripts to have their own test-suite nodes,
            # planned for v4.0
            $Pester.TestResult[-1].Describe = "Error in $($Feature.Path)"
    
            $Pester.TestResult[-1] | Write-PesterResult
        }
        finally {
            $Location | & $SafeCommands["Set-Location"]
            [Environment]::CurrentDirectory = $CWD
        }
    
        Invoke-GherkinHook AfterEachFeature $Feature.Name $Feature.Tags
    
        $Pester.LeaveTestGroup($Feature.Name, 'Script')
    
    }
    
    function Invoke-GherkinScenario {
        <#
            .SYNOPSIS
                Internal function to (parse and) run a single scenario
        #>
        [CmdletBinding()]
        param(
            $Pester, $Scenario, $Background, $Language
        )
        $Pester.EnterTestGroup($Scenario.Name, 'Scenario')
        try {
            # We just display 'Scenario', also for 'Scenario Outline' or 'Scenario Template'
            # Thus we use the translation of 'scenario' instead of $Scenario.Keyword
            Write-Context (New-Object PSObject -Property @{Name = "$(Get-Translation 'scenario' $Language): $($Scenario.Name)"; Description = $Scenario.Description })
    
            $script:mockTable = @{}
    
            # Create a clean variable scope in each scenario
            $script:GherkinScenarioScope = New-Module Scenario {       $a = 4
            }
            $script:GherkinSessionState = Set-SessionStateHint -PassThru -Hint Scenario -SessionState $Script:GherkinScenarioScope.SessionState
    
            #Wait-Debugger
    
            New-TestDrive
            Invoke-GherkinHook BeforeEachScenario $Scenario.Name $Scenario.Tags
    
            $testResultIndexStart = $Pester.TestResult.Count
    
            # If there's a background, run that before the test, but after hooks
            if ($Background) {
                foreach ($Step in $Background.Steps) {
                    # Run Background steps -Background so they don't output in each scenario
                    Invoke-GherkinStep -Step $Step -Pester $Pester -Scenario $GherkinSessionState -Visible -TestResultIndexStart $testResultIndexStart
                }
            }
    
            foreach ($Step in $Scenario.Steps) {
                Invoke-GherkinStep -Step $Step -Pester $Pester -Scenario $GherkinSessionState -Visible -TestResultIndexStart $testResultIndexStart
            }
    
            Invoke-GherkinHook AfterEachScenario $Scenario.Name $Scenario.Tags
        }
        catch {
            $firstStackTraceLine = $_.ScriptStackTrace -split '\r?\n' | & $SafeCommands["Select-Object"] -First 1
            $Pester.AddTestResult("Error occurred in scenario '$($Scenario.Name)'", "Failed", $null, $_.Exception.Message, $firstStackTraceLine, $null, $null, $_)
    
            # This is a hack to ensure that XML output is valid for now.  The test-suite names come from the Describe attribute of the TestResult
            # objects, and a blank name is invalid NUnit XML.  This will go away when we promote test scripts to have their own test-suite nodes,
            # planned for v4.0
            $Pester.TestResult[-1].Describe = "Error in $($Scenario.Name)"
    
            $Pester.TestResult[-1] | Write-PesterResult
        }
    
        Remove-TestDrive
        $Pester.LeaveTestGroup($Scenario.Name, 'Scenario')
        Exit-MockScope
    }
    
    function Find-GherkinStep {
        <#
            .SYNOPSIS
                Find a step implmentation that matches a given step
    
            .DESCRIPTION
                Searches the *.Steps.ps1 files in the BasePath (current working directory, by default)
                Returns the step(s) that match
    
            .PARAMETER Step
                The text from feature file
    
            .PARAMETER BasePath
                The path to search for step implementations.
    
            .EXAMPLE
                Find-GherkinStep -Step 'And the module is imported'
    
                Step                       Source                      Implementation
                ----                       ------                      --------------
                And the module is imported .\module.Steps.ps1: line 39 ...
        #>
    
        [CmdletBinding()]
        param(
    
            [string]$Step,
    
            [string]$BasePath = $Pwd
        )
    
        $OriginalGherkinSteps = $Script:GherkinSteps
        try {
            Import-GherkinSteps $BasePath -Pester $PSCmdlet
    
            $KeyWord, $StepText = $Step -split "(?<=^(?:Given|When|Then|And|But))\s+"
            if (!$StepText) {
                $StepText = $KeyWord
            }
    
            & $SafeCommands["Write-Verbose"] "Searching for '$StepText' in $($Script:GherkinSteps.Count) steps"
            $(
                foreach ($StepCommand in $Script:GherkinSteps.Keys) {
                    & $SafeCommands["Write-Verbose"] "... $StepCommand"
                    if ($StepText -match "^${StepCommand}$") {
                        & $SafeCommands["Write-Verbose"] "Found match: $StepCommand"
                        $StepCommand | & $SafeCommands["Add-Member"] -MemberType NoteProperty -Name MatchCount -Value $Matches.Count -PassThru
                    }
                }
            ) | & $SafeCommands["Sort-Object"] MatchCount | & $SafeCommands["Select-Object"] @{
                Name       = 'Step'
                Expression = { $Step }
            }, @{
                Name       = 'Source'
                Expression = { $Script:GherkinSteps["$_"].Source }
            }, @{
                Name       = 'Implementation'
                Expression = { $Script:GherkinSteps["$_"] }
            } -First 1
    
            # $StepText = "{0} {1} {2}" -f $Step.Keyword.Trim(), $Step.Text, $Script:GherkinSteps[$StepCommand].Source
    
        }
        finally {
            $Script:GherkinSteps = $OriginalGherkinSteps
        }
    }
    
    function Invoke-GherkinStep {
        <#
            .SYNOPSIS
                Run a single gherkin step, given the text from the feature file
    
            .PARAMETER Step
                The text of the step for matching against regex patterns in step implementations
    
            .PARAMETER Visible
                If Visible is true, the results of this step will be shown in the test report
    
            .PARAMETER Pester
                Pester state object. For internal use only
    
            .PARAMETER ScenarioState
                Gherkin state object. For internal use only
    
            .PARAMETER TestResultIndexStart
                Used to hold the test result index of the first step of the current scenario. For internal use only
        #>
        [CmdletBinding()]
        param (
            $Step,
    
            [Switch]$Visible,
    
            $Pester,
    
            $ScenarioState,
    
            [int] $TestResultIndexStart
        )
        if ($Step -is [string]) {
            $KeyWord, $StepText = $Step -split "(?<=^(?:Given|When|Then|And|But))\s+"
            if (!$StepText) {
                $StepText = $KeyWord
                $Keyword = "Step"
            }
            $Step = @{ Text = $StepText; Keyword = $Keyword }
        }
        $DisplayText = "{0} {1}" -f $Step.Keyword.Trim(), $Step.Text
    
        $PesterErrorRecord = $null
        $Elapsed = $null
        $NamedArguments = @{}
    
        try {
            #  Pick the match with the least grouping wildcards in it...
            $StepCommand = $(
                foreach ($StepCommand in $Script:GherkinSteps.Keys) {
                    if ($Step.Text -match "^${StepCommand}$") {
                        $StepCommand | & $SafeCommands["Add-Member"] -MemberType NoteProperty -Name MatchCount -Value $Matches.Count -PassThru
                    }
                }
            ) | & $SafeCommands["Sort-Object"] MatchCount | & $SafeCommands["Select-Object"] -First 1
    
            $previousStepsNotSuccessful = $false
            # Iterate over the test results of the previous steps
            for ($i = $TestResultIndexStart; $i -lt ($Pester.TestResult.Count); $i++) {
                $previousTestResult = $Pester.TestResult[$i].Result
                if ($previousTestResult -eq "Failed" -or $previousTestResult -eq "Inconclusive") {
                    $previousStepsNotSuccessful = $true
                    break
                }
            }
            if (!$StepCommand -or $previousStepsNotSuccessful) {
                $skipMessage = if (!$StepCommand) {
                    "Could not find implementation for step!"
                }
                else {
                    "Step skipped (previous step did not pass)"
                }
                $PesterErrorRecord = New-PesterErrorRecord -Result Inconclusive -Message $skipMessage -File $Step.Location.Path -Line $Step.Location.Line -LineText $DisplayText
            }
            else {
                $NamedArguments, $Parameters = Get-StepParameters $Step $StepCommand
                $watch = & $SafeCommands["New-Object"] System.Diagnostics.Stopwatch
                $watch.Start()
                try {
                    # Invoke-GherkinHook BeforeStep $Step.Text $Step.Tags
    
                    if ($NamedArguments.Count) {
                        if ($NamedArguments.ContainsKey("Table")) {
                            $DisplayText += "..."
                        }
                        $ScriptBlock = { . $Script:GherkinSteps.$StepCommand @NamedArguments @Parameters }
                    }
                    else {
                        $ScriptBlock = { . $Script:GherkinSteps.$StepCommand @Parameters }
                    }
                    Set-ScriptBlockScope -ScriptBlock $Script:GherkinSteps.$StepCommand -SessionState $ScenarioState
    
                    Write-ScriptBlockInvocationHint -Hint "Invoke-Gherkin step" -ScriptBlock $Script:GherkinSteps.$StepCommand
                    $null = & $ScriptBlock
                }
                catch {
                    $PesterErrorRecord = $_
                }
                $watch.Stop()
                $Elapsed = $watch.Elapsed
            }
        }
        catch {
            $PesterErrorRecord = $_
        }
    
        if ($Pester -and $Visible) {
            for ($p = 0; $p -lt $Parameters.Count; $p++) {
                $NamedArguments."Unnamed-$p" = $Parameters[$p]
            }
    
            # Normally, PesterErrorRecord is an ErrorRecord. Sometimes, it's an exception which HAS A ErrorRecord
            if ($PesterErrorRecord.ErrorRecord) {
                $PesterErrorRecord = $PesterErrorRecord.ErrorRecord
            }
    
            ${Pester Result} = ConvertTo-PesterResult -ErrorRecord $PesterErrorRecord
    
            # For Gherkin, we want to show the step, but not pretend to be a StackTrace
            if (${Pester Result}.Result -eq 'Inconclusive') {
                ${Pester Result}.StackTrace = "At " + $Step.Keyword.Trim() + ', ' + $Step.Location.Path + ': line ' + $Step.Location.Line
            }
            else {
                # Unless we really are a StackTrace...
                ${Pester Result}.StackTrace += "`nFrom " + $Step.Location.Path + ': line ' + $Step.Location.Line
            }
            $Pester.AddTestResult($DisplayText, ${Pester Result}.Result, $Elapsed, ${Pester Result}.FailureMessage, ${Pester Result}.StackTrace, $null, $NamedArguments, $PesterErrorRecord)
            $Pester.TestResult[-1] | Write-PesterResult
        }
    }
    
    function Get-StepParameters {
        <#
            .SYNOPSIS
                Internal function for determining parameters for a step implementation
            .PARAMETER Step
                The parsed step from the feature file
    
            .PARAMETER CommandName
                The text of the best matching step
        #>
        param($Step, $CommandName)
        $Null = $Step.Text -match $CommandName
    
        $NamedArguments = @{}
        $Parameters = @{}
        foreach ($kv in $Matches.GetEnumerator()) {
            switch ($kv.Name -as [int]) {
                0 {
                } # toss zero (where it matches the whole string)
                $null {
                    $NamedArguments.($kv.Name) = $ExecutionContext.InvokeCommand.ExpandString($kv.Value)
                }
                default {
                    $Parameters.([int]$kv.Name) = $ExecutionContext.InvokeCommand.ExpandString($kv.Value)
                }
            }
        }
        $Parameters = @($Parameters.GetEnumerator() | & $SafeCommands["Sort-Object"] Name | & $SafeCommands["Select-Object"] -ExpandProperty Value)
    
        # TODO: Convert parsed tables to tables....
        if ($Step.Argument -is [Gherkin.Ast.DataTable]) {
            $NamedArguments.Table = $Step.Argument.Rows | ConvertTo-HashTableArray
        }
        if ($Step.Argument -is [Gherkin.Ast.DocString]) {
            # trim empty matches if we're attaching DocStringArgument
            $Parameters = @( $Parameters | & $SafeCommands["Where-Object"] { $_.Length } ) + $Step.Argument.Content
        }
    
        return @($NamedArguments, $Parameters)
    }
    
    function Convert-Tags {
        <#
            .SYNOPSIS
                Internal function for tagging Gherkin feature files (including inheritance from the feature)
        #>
        [CmdletBinding()]
        param(
            [Parameter(ValueFromPipeline = $true)]
            $InputObject,
    
            [Parameter(Position = 0)]
            [string[]]$BaseTags = @()
        )
        process {
            # Adapt the Gherkin .Tags property to the way we prefer it...
            [string[]]$Tags = foreach ($tag in $InputObject.Tags | & $SafeCommands['Where-Object'] { $_ }) {
                $tag.Name.TrimStart("@")
            }
            & $SafeCommands["Add-Member"] -MemberType NoteProperty -InputObject $InputObject -Name Tags -Value ([string[]]($Tags + $BaseTags)) -Force
            $InputObject
        }
    }
    
    function ConvertTo-HashTableArray {
        <#
            .SYNOPSIS
                Internal function for converting Gherkin AST tables to arrays of hashtables for splatting
        #>
        [CmdletBinding()]
        param(
            [Parameter(ValueFromPipeline = $true)]
            [Gherkin.Ast.TableRow[]]$InputObject
        )
        begin {
            ${Column Names} = @()
            ${Result Table} = @()
        }
        process {
            # Convert the first table row into headers:
            ${InputObject Rows} = @($InputObject)
            if (!${Column Names}) {
                & $SafeCommands["Write-Verbose"] "Reading Names from Header"
                ${InputObject Header}, ${InputObject Rows} = ${InputObject Rows}
                ${Column Names} = @(${InputObject Header}.Cells | & $SafeCommands["Select-Object"] -ExpandProperty Value)
            }
    
            if ( $null -ne ${InputObject Rows} ) {
                & $SafeCommands["Write-Verbose"] "Processing $(${InputObject Rows}.Length) Rows"
                foreach (${InputObject row} in ${InputObject Rows}) {
                    ${Pester Result} = @{}
                    for ($n = 0; $n -lt ${Column Names}.Length; $n++) {
                        ${Pester Result}.Add(${Column Names}[$n], ${InputObject row}.Cells[$n].Value)
                    }
                    ${Result Table} += @(${Pester Result})
                }
            }
        }
        end {
            ${Result Table}
        }
    }
    
    function Get-Translations($TranslationKey, $Language) {
        <#
            .SYNOPSIS
                Internal function to get all translations for a translation key and language
    
            .PARAMETER TranslationKey
                The key name inside the language in gherkin-languages.json, e.g. 'scenarioOutline'
    
            .PARAMETER Language
                The used language, e.g. 'en'
    
            .OUTPUTS
                System.String[] an array of all the translations
        #>
        if (-not (Test-Path variable:Script:GherkinLanguagesJson)) {
            $Script:GherkinLanguagesJson = ConvertFrom-Json2 (Get-Content "${Script:PesterRoot}/lib/Gherkin/gherkin-languages.json" | Out-String)
            # We override the fixed values for 'Describe' and 'Context' of Gherkin.psd1 or Output.ps1 since the language aware keywords
            # (e.g. 'Feature'/'Funktionalität' or 'Scenario'/'Szenario') are provided by Gherkin.dll and we do not want to duplicate them.
            $Script:ReportStrings.Describe = "{0}" # instead of 'Feature: {0}'  or 'Describing {0}'
            $Script:ReportStrings.Context = "{0}" # instead of 'Scenario: {0}' or 'Context {0}'
        }
        $foundTranslations = $Script:GherkinLanguagesJson."$Language"."$TranslationKey"
        if (-not $foundTranslations) {
            Write-Warning "Translation key '$TranslationKey' is invalid"
        }
        return , $foundTranslations
    }
    
    function ConvertFrom-Json2([string] $jsonString) {
        <#
            .SYNOPSIS
                Internal function to convert from JSON even for PowerShell 2
    
            .PARAMETER jsonString
                The JSON content as string
    
            .OUTPUTS
                the JSON content as array
        #>
        if ($PSVersionTable.PSVersion.Major -le 2) {
            # On PowerShell <= 2 we use JavaScriptSerializer
            Add-Type -Assembly System.Web.Extensions
            return , (New-Object System.Web.Script.Serialization.JavaScriptSerializer).DeserializeObject($jsonString)
        }
        else {
            # On PowerShell > 2 we use the built-in ConvertFrom-Json cmdlet
            return ConvertFrom-Json $jsonString
        }
    }
    
    function Get-Translation($TranslationKey, $Language, $Index = -1) {
        <#
            .SYNOPSIS
                Internal function to get the first translation for a translation key and language
    
            .PARAMETER TranslationKey
                The key name inside the language in gherkin-languages.json, e.g. 'scenarioOutline'
    
            .PARAMETER Language
                The used language, e.g. 'en'
    
            .PARAMETER Index
                The index in the array of JSON values
                If -1 is used for Index (the default value), this function will choose the most common translation of the JSON values
    
            .OUTPUTS
                System.String the chosen translation
        #>
        $translations = (Get-Translations $TranslationKey $Language)
        if (-not $translations) {
            return
        }
        if ($Index -lt 0 -or $Index -ge $translations.Length) {
            # Fallback: if the index is not in range, we choose the most common translation
            # Normally, the most common translation will be found at index one, but under some keys the index is zero.
            $Index = if ($TranslationKey -eq "scenarioOutline" -or $TranslationKey -eq "feature" -or $TranslationKey -eq "examples") {
                0
            }
            else {
                1
            }
        }
        return $translations[$Index]
    }
    
    function Test-Keyword($Keyword, $TranslationKey, $Language) {
        <#
            .SYNOPSIS
                Internal function to check if the given keyword matches one of the translations for a translation key and language
    
            .PARAMETER Keyword
                The keyword, e.g. 'Scenario Outline'
    
            .PARAMETER TranslationKey
                The key name inside the language in gherkin-languages.json, e.g. 'scenarioOutline'
    
            .PARAMETER Language
                The used language, e.g. 'en'
    
            .OUTPUTS
                System.Boolean true, if the keyword matches one of the translations, false otherwise
        #>
        return (Get-Translations $TranslationKey $Language) -contains $Keyword
    }
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQU7bvzcTQCpY9ENqdEyG3Rzwpf
    # rfuggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # aLGXTFSRyRc6GNdS+rQKlIHb7CQwDQYJKoZIhvcNAQEBBQAEggEAAH31g5Rx4J2b
    # KUj17PU27frpQ+UEy1n7g0kkHTHy0RpohchdlbwIYFqkAdrGU/ICKaG4r3BDWPYr
    # /r/s8pRycpv/uXfV+xDt28tuUBXkp3ermvXhvbcVHX5fnUb6BkLBo7oU89sbyWsa
    # jZEEmOz34XElugTRKWDj21dkR5Ewh3NJCY3/a2iBpdfZ7NZQWLlEsumW0N7FiwHg
    # Hb+wdJ3vIbbhllg9vYpBnkvwh58ieuYPQ94cwQOVYJwgq7wDvHumB4p8+Z0iE0Uf
    # KLGRpNXuwr0R7LHU0RX48nMFQYQpTgDiZrFoZ/hpQKcn4J54oahJaC3pccJ6rjGi
    # H5oDaRTLG6GCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzM3WjAjBgkqhkiG9w0BCQQx
    # FgQUfdh280uZPQM6p4DvT3p8+vrB+IwwDQYJKoZIhvcNAQEBBQAEggEACgygfrn3
    # z3TTGlGvPMFTnkADstWyflW4ed2S3okcSoXBrSqZhFLBcogTX+hTEp2ziA2iIh/L
    # Iw6h88++NXRWsRPWo0RywzIty8+48LSs2KX39Ss69RHadKKnJDjqy/QL25MyU4uf
    # PPcCBxYfGL/A9XO5yL+iVS45q1sJrfnWO3Tq9Ojmt52CgUNuMBB27TSNwkYL34M0
    # jAx2NsSvpr9D98nj+xrhVoIfo8LQ5ZnM2V3EUNmZW1+PYMg4NPq6XKP9Ze6DkWL1
    # upnV/8RJGnKEulc6gIHh+hdKhUvn6D7x17KLNKx8As1ZHipIS7ITolKl60lYQMJm
    # uuULu5itaehYiw==
    # SIG # End signature block
    
  • tools\Functions\Gherkin.types.ps1xml
  • tools\Functions\GherkinHook.ps1 Show
    function BeforeEachFeature {
        <#
            .SYNOPSIS
            Defines a ScriptBlock hook to run before each feature to set up the test environment
    
            .DESCRIPTION
            BeforeEachFeature hooks are run before each feature that is in (or above) the folder where the hook is defined.
    
            This is a convenience method, provided because unlike traditional RSpec Pester,
            there is not a simple test script where you can put setup and clean up.
    
            .PARAMETER Tags
            Optional tags. If set, this hook only runs for features with matching tags
    
            .PARAMETER Script
            The ScriptBlock to run for the hook
    
            .LINK
            AfterEachFeature
            BeforeEachScenario
            AfterEachScenario
        #>
        [CmdletBinding(DefaultParameterSetName = "All")]
        param(
    
            [Parameter(Mandatory = $True, Position = 0, ParameterSetName = "Tags")]
            [String[]]$Tags = @(),
    
            [Parameter(Mandatory = $True, Position = 1, ParameterSetName = "Tags")]
            [Parameter(Mandatory = $True, Position = 0, ParameterSetName = "All")]
            [ScriptBlock]$Script
        )
    
        # This shouldn't be necessary, but PowerShell 2 is BAF
        if ($PSCmdlet.ParameterSetName -eq "Tags") {
            ${Script:GherkinHooks}.BeforeEachFeature += @( @{ Tags = $Tags; Script = $Script } )
        }
        else {
            ${Script:GherkinHooks}.BeforeEachFeature += @( @{ Tags = @(); Script = $Script } )
        }
    }
    
    function AfterEachFeature {
        <#
            .SYNOPSIS
            Defines a ScriptBlock hook to run at the very end of a test run
    
            .DESCRIPTION
            AfterEachFeature hooks are run after each feature that is in (or above) the folder where the hook is defined.
    
            This is a convenience method, provided because unlike traditional RSpec Pester,
            there is not a simple test script where you can put setup and clean up.
    
            .PARAMETER Tags
            Optional tags. If set, this hook only runs for features with matching tags.
    
            .PARAMETER Script
            The ScriptBlock to run for the hook
    
            .LINK
                BeforeEachFeature
                BeforeEachScenario
                AfterEachScenario
        #>
        [CmdletBinding(DefaultParameterSetName = "All")]
        param(
    
            [Parameter(Mandatory = $True, Position = 0, ParameterSetName = "Tags")]
            [String[]]$Tags = @(),
    
            [Parameter(Mandatory = $True, Position = 1, ParameterSetName = "Tags")]
            [Parameter(Mandatory = $True, Position = 0, ParameterSetName = "All")]
            [ScriptBlock]$Script
        )
    
        # This shouldn't be necessary, but PowerShell 2 is BAF
        if ($PSCmdlet.ParameterSetName -eq "Tags") {
            ${Script:GherkinHooks}.AfterEachFeature += @( @{ Tags = $Tags; Script = $Script } )
        }
        else {
            ${Script:GherkinHooks}.AfterEachFeature += @( @{ Tags = @(); Script = $Script } )
        }
    }
    
    function BeforeEachScenario {
        <#
            .SYNOPSIS
            Defines a ScriptBlock hook to run before each scenario to set up the test environment
    
            .DESCRIPTION
            BeforeEachScenario hooks are run before each scenario that is in (or above) the folder where the hook is defined.
    
            You should not normally need this, because it overlaps significantly with the "Background" feature in the gherkin language.
    
            This is a convenience method, provided because unlike traditional RSpec Pester,
            there is not a simple test script where you can put setup and clean up.
    
            .PARAMETER Tags
            Optional tags. If set, this hook only runs for features with matching tags
    
            .PARAMETER Script
            The ScriptBlock to run for the hook
    
            .LINK
            AfterEachFeature
            BeforeEachScenario
            AfterEachScenario
        #>
        [CmdletBinding(DefaultParameterSetName = "All")]
        param(
    
            [Parameter(Mandatory = $True, Position = 0, ParameterSetName = "Tags")]
            [String[]]$Tags = @(),
    
            [Parameter(Mandatory = $True, Position = 1, ParameterSetName = "Tags")]
            [Parameter(Mandatory = $True, Position = 0, ParameterSetName = "All")]
            [ScriptBlock]$Script
        )
    
        # This shouldn't be necessary, but PowerShell 2 is BAF
        if ($PSCmdlet.ParameterSetName -eq "Tags") {
            ${Script:GherkinHooks}.BeforeEachScenario += @( @{ Tags = $Tags; Script = $Script } )
        }
        else {
            ${Script:GherkinHooks}.BeforeEachScenario += @( @{ Tags = @(); Script = $Script } )
        }
    }
    
    function AfterEachScenario {
        <#
            .SYNOPSIS
            Defines a ScriptBlock hook to run after each scenario to set up the test environment
    
            .DESCRIPTION
            AfterEachScenario hooks are run after each Scenario that is in (or above) the folder where the hook is defined.
    
            This is a convenience method, provided because unlike traditional RSpec Pester,
            there is not a simple test script where you can put setup and clean up.
    
            .PARAMETER Tags
            Optional tags. If set, this hook only runs for features with matching tags
    
            .PARAMETER Script
            The ScriptBlock to run for the hook
    
            .LINK
                BeforeEachFeature
                BeforeEachScenario
                AfterEachScenario
        #>
        [CmdletBinding(DefaultParameterSetName = "All")]
        param(
            [Parameter(Mandatory = $True, Position = 0, ParameterSetName = "Tags")]
            [String[]]$Tags = @(),
    
            [Parameter(Mandatory = $True, Position = 1, ParameterSetName = "Tags")]
            [Parameter(Mandatory = $True, Position = 0, ParameterSetName = "All")]
            [ScriptBlock]$Script
        )
    
        # This shouldn't be necessary, but PowerShell 2 is BAF
        if ($PSCmdlet.ParameterSetName -eq "Tags") {
            ${Script:GherkinHooks}.AfterEachScenario += @( @{ Tags = $Tags; Script = $Script } )
        }
        else {
            ${Script:GherkinHooks}.AfterEachScenario += @( @{ Tags = @(); Script = $Script } )
        }
    }
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQU6+OAExRC+0GA4ggglPLenQ/7
    # GPOggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # tI1liOZUbONpldmcupzXDzz0mHowDQYJKoZIhvcNAQEBBQAEggEAb5iEIVAskmtd
    # EvSnnhntiOhz4ZXhU6EgvwROHte7R1r9fMucD/rMulafoqU/0uZGCyqMOFg0vt2i
    # KWOL0P/cxQKoHkbU6fRVrQVX00aNPmxcaSVpd/Lqyj3m5fs69UwR6ggBsCPmfxuT
    # Tt7xWjVfleTx/A1ONKNN00n+TXyZnrFcKJHGMepFuZFV+n6FT157GZ3BHSIeM6eX
    # sE9ey2joE9IGzONlW3GycAoD4i6zgovlBdyn6B9kYSy3KuzImg10UWLXngqXedIx
    # qXIlCoCuC1KdfW11szWLckQLuVdlmAtwGVzAv+pAHgtdeXyDBjjqyiiV5BvdjFvX
    # z7j/mO31KqGCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzM3WjAjBgkqhkiG9w0BCQQx
    # FgQU+6BB3O6xUtiC2NiQWkZJjHoUv3MwDQYJKoZIhvcNAQEBBQAEggEAPTxGHtS8
    # k/nJADBzC6gEC+9TQcQiDSPSwJTD5bOLXIi8FA+Np7XTpXf1xYwUsY8M2cBxnFKg
    # 9E3EteF3yb++0vqxQrjeUk+gV9UEyfsKlDJEVdPEY/Be5xSE2Em0KFAgOh35NLmm
    # qTAGuAdmuLoPiTRR7jWqf6rO4UxmDuNnWvh5RIxxVNGbC8MoVB3+prUPuIuHamhw
    # hajCOgWDo2e7OCYrh9HVqgMXBNmx5oHLVQ5tL04nUtYqrND8CzhGPPmMa6fll72/
    # q15DQknasPiUkyWm07+jFM8M1uDf7nuY4ZzIVbtRxmV1d4vhBR2uuWEFazvvMWqy
    # 13+nDKXQpwlqNQ==
    # SIG # End signature block
    
  • tools\Functions\Assertions\BeGreaterThan.ps1 Show
    function Should-BeGreaterThan($ActualValue, $ExpectedValue, [switch] $Negate, [string] $Because) {
        <#
    .SYNOPSIS
    Asserts that a number (or other comparable value) is greater than an expected value.
    Uses PowerShell's -gt operator to compare the two values.
    
    .EXAMPLE
    2 | Should -BeGreaterThan 0
    This test passes, as PowerShell evaluates `2 -gt 0` as true.
    #>
        if ($Negate) {
            return Should-BeLessOrEqual -ActualValue $ActualValue -ExpectedValue $ExpectedValue -Negate:$false -Because $Because
        }
    
        if ($ActualValue -le $ExpectedValue) {
            return New-Object psobject -Property @{
                Succeeded      = $false
                FailureMessage = "Expected the actual value to be greater than $(Format-Nicely $ExpectedValue),$(Format-Because $Because) but got $(Format-Nicely $ActualValue)."
            }
        }
    
        return New-Object psobject -Property @{
            Succeeded = $true
        }
    }
    
    
    function Should-BeLessOrEqual($ActualValue, $ExpectedValue, [switch] $Negate, [string] $Because) {
        <#
    .SYNOPSIS
    Asserts that a number (or other comparable value) is lower than, or equal to an expected value.
    Uses PowerShell's -le operator to compare the two values.
    
    .EXAMPLE
    1 | Should -BeLessOrEqual 10
    This test passes, as PowerShell evaluates `1 -le 10` as true.
    
    .EXAMPLE
    10 | Should -BeLessOrEqual 10
    This test also passes, as PowerShell evaluates `10 -le 10` as true.
    #>
        if ($Negate) {
            return Should-BeGreaterThan -ActualValue $ActualValue -ExpectedValue $ExpectedValue -Negate:$false -Because $Because
        }
    
        if ($ActualValue -gt $ExpectedValue) {
            return New-Object psobject -Property @{
                Succeeded      = $false
                FailureMessage = "Expected the actual value to be less than or equal to $(Format-Nicely $ExpectedValue),$(Format-Because $Because) but got $(Format-Nicely $ActualValue)."
            }
        }
    
        return New-Object psobject -Property @{
            Succeeded = $true
        }
    }
    
    Add-AssertionOperator -Name         BeGreaterThan `
        -InternalName Should-BeGreaterThan `
        -Test         ${function:Should-BeGreaterThan} `
        -Alias        'GT'
    
    Add-AssertionOperator -Name         BeLessOrEqual `
        -InternalName Should-BeLessOrEqual `
        -Test         ${function:Should-BeLessOrEqual} `
        -Alias        'LE'
    
    #keeping tests happy
    function ShouldBeGreaterThanFailureMessage() {
    }
    function NotShouldBeGreaterThanFailureMessage() {
    }
    
    function ShouldBeLessOrEqualFailureMessage() {
    }
    function NotShouldBeLessOrEqualFailureMessage() {
    }
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUNzhWrZj1EvL4bWFmv5tSKNnQ
    # sFyggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # kbq7WTLHTCunkI4Ag5RwkaqRGrYwDQYJKoZIhvcNAQEBBQAEggEAa/r87oeQ9URU
    # rRSzH3Pv/r6xxDyIyVBceOlKQZW/esfaBZlIWg8IbVkMQHnDRSJS7YXknrlFXzZx
    # utxf52uY9YzabIHt5SAkOZZAMn9pnyNRXFxwphs2tSfSnYqQ5lMaJSXpF8i9jC7h
    # /FNhZBPcuIe+VBADYy0vL1oB/h6lQpx7AAaazw87kmH5RvWUcBlm0t0D8E6zDggH
    # yVkShZqcWdd54ByAEVw4R+78YPfQ/4GdL6/Kau0qroKohOm8HeXy6xYbyDNTURPY
    # kA5rN3MJL61nHLSOxwCW/3aKeq8M6QSfy8crFRatXv8SlKpgkBZf5Ih2WsqCCw1V
    # l5F82Gp2L6GCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzQ4WjAjBgkqhkiG9w0BCQQx
    # FgQUfKAaDDYMYexf4zXiBPKObtt/NZAwDQYJKoZIhvcNAQEBBQAEggEARBz4Tr8r
    # +VyBxulZMTqjGDIhFeL7+88imhIXS5Lh6emvkD71Jhgx0Yuj8VTX7pSIF1cZ16xd
    # ta4RyHUmq5qZEG2i+DVZsb6jL6W6/fEHf3drUuIiCDq6BADv0CGJ+keq93cXOh4x
    # KwPdlM29A+LVZL9Jt5xeaWCPEAeIu/86YP3z9OsYMwLc4tF3Xh8ckKNRJLJzb9lS
    # Bj+L2bFv7+j3gix3oqQpd8QeptTuzDdY8f5+4pM2f0sX3gANoFdggzattq5c5Rvo
    # mCvE0/BS8qhH9Zv0ZRGzgWB52NebKnGlO+/E5haYZ2AGIRRgSNYMQHrtyZQne2Ut
    # n0TgcsbxWBhIhA==
    # SIG # End signature block
    
  • tools\Functions\In.ps1 Show
    function In {
        <#
        .SYNOPSIS
        A convenience function that executes a script from a specified path.
    
        .DESCRIPTION
        Before the script block passed to the execute parameter is invoked,
        the current location is set to the path specified. Once the script
        block has been executed, the location will be reset to the location
        the script was in prior to calling In.
    
        .PARAMETER Path
        The path that the execute block will be executed in.
    
        .PARAMETER execute
        The script to be executed in the path provided.
    
        .LINK
        https://github.com/pester/Pester/wiki/In
    
        #>
        [CmdletBinding()]
        param(
            $path,
            [ScriptBlock] $execute
        )
        Assert-DescribeInProgress -CommandName In
    
        $old_pwd = $pwd
        & $SafeCommands['Push-Location'] $path
        $pwd = $path
        try {
            Write-ScriptBlockInvocationHint -Hint "In" -ScriptBlock $execute
            & $execute
        }
        finally {
            & $SafeCommands['Pop-Location']
            $pwd = $old_pwd
        }
    }
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUM48T/5L1hnCTGcPNwM+NKVOk
    # LjKggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # l/TSAQpaTpRl5sxHtSowURmQ2oMwDQYJKoZIhvcNAQEBBQAEggEASQxDp95+88ig
    # mbBJmeMqAlk5GlRVslUIphUq1C38S5NccmcecoKUaxYpqjugW2gDWjbRWdZAH7R4
    # cycBUgBOsYUfJkrw8r/U9zKsGde8Ng7zXEznbFn+1pD2fJqjGlaH1u+gpUXuETVZ
    # EXUxHO8wQ9dZ0U3I0CHh+m9/QrU8QEHMx7jqYQLddYTa4SQbboBshrI+QtjLg7tP
    # ivFbd6pdz74NC2Mvv6vuh/e92S6m87ifkfsTdUUlOv7nS0BI9c8gIs2V+JrO7Fg/
    # /8Zc9WIMQME9IEl31kr9D3/36xj0e2cFV3Fr6p5DlAricMLl2BOSjQ2EEc0dJ9eQ
    # vw+hOdBacKGCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzM5WjAjBgkqhkiG9w0BCQQx
    # FgQUk7POyVQJPgsP40Y4lfhBp5MQ7ekwDQYJKoZIhvcNAQEBBQAEggEADs2PzLnQ
    # 9a5QTc1Q6c0wLUMgvZRflEQQc2m/hQ7QhFoZE0irYX2Xsd29l+NsT4h4SpWpMZhm
    # I65b62cXove7Nsq/6PFnLUob4cnvAZhL+rEcPPNuku65a7RtpAHQmBxmJiWdrD2x
    # TGTDCQhiDCX96SaGMR/3TFv50h7g6yypBKIeFt13F5YIA2TxkYX23OeU2582rENA
    # 4urMg2c9zu1pfYd9av8LYlE4v+W2DwBk5VwthNsplre+E+R+K+RssXFI8oxSPS2f
    # 7yjjwKgJRl/HpwU4wVX71danfhuuueFYhQTWS9yu6BFjRnzWqmWdmOS2WQa+abd0
    # JNGy0P59EzVUnA==
    # SIG # End signature block
    
  • tools\Functions\InModuleScope.ps1 Show
    function InModuleScope {
        <#
    .SYNOPSIS
       Allows you to execute parts of a test script within the
       scope of a PowerShell script module.
    .DESCRIPTION
       By injecting some test code into the scope of a PowerShell
       script module, you can use non-exported functions, aliases
       and variables inside that module, to perform unit tests on
       its internal implementation.
    
       InModuleScope may be used anywhere inside a Pester script,
       either inside or outside a Describe block.
    .PARAMETER ModuleName
       The name of the module into which the test code should be
       injected. This module must already be loaded into the current
       PowerShell session.
    .PARAMETER ScriptBlock
       The code to be executed within the script module.
    .EXAMPLE
        # The script module:
        function PublicFunction
        {
            # Does something
        }
    
        function PrivateFunction
        {
            return $true
        }
    
        Export-ModuleMember -Function PublicFunction
    
        # The test script:
    
        Import-Module MyModule
    
        InModuleScope MyModule {
            Describe 'Testing MyModule' {
                It 'Tests the Private function' {
                    PrivateFunction | Should -Be $true
                }
            }
        }
    
        Normally you would not be able to access "PrivateFunction" from
        the PowerShell session, because the module only exported
        "PublicFunction".  Using InModuleScope allowed this call to
        "PrivateFunction" to work successfully.
    #>
    
        [CmdletBinding()]
        param (
            [Parameter(Mandatory = $true)]
            [string]
            $ModuleName,
    
            [Parameter(Mandatory = $true)]
            [scriptblock]
            $ScriptBlock
        )
    
        if ($null -eq (& $SafeCommands['Get-Variable'] -Name Pester -ValueOnly -ErrorAction $script:IgnoreErrorPreference)) {
            # User has executed a test script directly instead of calling Invoke-Pester
            $sessionState = Set-SessionStateHint -PassThru -Hint "Caller - Captured in InModuleScope" -SessionState $PSCmdlet.SessionState
            $Pester = New-PesterState -Path (& $SafeCommands['Resolve-Path'] .) -TestNameFilter $null -TagFilter @() -ExcludeTagFilter @() -SessionState $sessionState
            $script:mockTable = @{}
        }
    
        $module = Get-ScriptModule -ModuleName $ModuleName -ErrorAction Stop
    
        $originalState = $Pester.SessionState
        $originalScriptBlockScope = Get-ScriptBlockScope -ScriptBlock $ScriptBlock
    
        try {
            $sessionState = Set-SessionStateHint -PassThru -Hint "Module - $($module.Name)" -SessionState $module.SessionState
            $Pester.SessionState = $sessionState
            Set-ScriptBlockScope -ScriptBlock $ScriptBlock -SessionState $sessionState
    
            do {
                Write-ScriptBlockInvocationHint -Hint "InModuleScope" -ScriptBlock $ScriptBlock
                & $ScriptBlock
            } until ($true)
        }
        finally {
            $Pester.SessionState = $originalState
            Set-ScriptBlockScope -ScriptBlock $ScriptBlock -SessionStateInternal $originalScriptBlockScope
        }
    }
    
    function Get-ScriptModule {
        [CmdletBinding()]
        param (
            [Parameter(Mandatory = $true)]
            [string] $ModuleName
        )
    
        try {
            $modules = @(& $SafeCommands['Get-Module'] -Name $ModuleName -All -ErrorAction Stop)
        }
        catch {
            throw "No module named '$ModuleName' is currently loaded."
        }
    
        $scriptModules = @($modules | & $SafeCommands['Where-Object'] { $_.ModuleType -eq 'Script' })
    
        if ($modules.Count -eq 0) {
            throw "No module named '$ModuleName' is currently loaded."
        }
    
        if ($scriptModules.Count -gt 1) {
            throw "Multiple Script modules named '$ModuleName' are currently loaded.  Make sure to remove any extra copies of the module from your session before testing."
        }
    
        if ($scriptModules.Count -eq 0) {
            $actualTypes = @(
                $modules |
                    & $SafeCommands['Where-Object'] { $_.ModuleType -ne 'Script' } |
                    & $SafeCommands['Select-Object'] -ExpandProperty ModuleType -Unique
            )
    
            $actualTypes = $actualTypes -join ', '
    
            throw "Module '$ModuleName' is not a Script module.  Detected modules of the following types: '$actualTypes'"
        }
    
        return $scriptModules[0]
    }
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUsL2aO1BkX4a3iPKp/42CagIX
    # NnKggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # jB4Sj+L1GHKryq5FQj4nLRzPNnQwDQYJKoZIhvcNAQEBBQAEggEAUYc2i+RwoRBi
    # dqBLlaLbd3W3P8BfqqIYhK7SvGa+9mCQbws4BwvqJZXQtSRPLseDfjv7UE/hGBni
    # KvqaeEuxS56jVSFC4VNWP7PNpEaRW6KXs1YRI7fkbRJ51hP3fQqWSkjtiwCp2OcP
    # n0w6mginlB7qEJaPTNPM7t935MEZ8Nnnwvlb3yS+KJviJ6FMhUhPgeonq6HmTsvJ
    # tqXhDqkHlTWBL7ZSzMX620BF4ewg1cy2fYJmElXExgO0AHtpGrRrWCRaEATCiw6X
    # nsHw6I/5SJXe1uPzs1vBuuLSkP0KuqWTByoESaj3PXl5h/M+294yi9pyvKWTd5kF
    # 5L7q5U1Ok6GCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzM5WjAjBgkqhkiG9w0BCQQx
    # FgQUKJeK/Tj0iY7ZrvzqZbiYsw4WqgcwDQYJKoZIhvcNAQEBBQAEggEAhWIWjmeE
    # hybJbnqiYPxlg6snv7zn8dcYbIjAd7k5gqttdTGu0oUeHuVysD5GwcrYU6pEgixy
    # 4CjfvzXhLiQRs31vJj163Vc4kkHvNpGl/cNJxhhxwjIakSSU2eqn1KAdc+aQT8/3
    # fVaxKBsg9Pk2c2hGLMdBAZv9D4Bb8eM2aV6SlRApmQRbMj/ymzLYzmHyH0lOl2TP
    # geGonN8KIHt0gmDfPlo/sP7vcALKwupynUf30f0WZkdmnOHHNZxZwTuBg2RlDEcc
    # 8OhN66to0jusKT7KUoNO/spo/P9R4XMW2+68BCZwWEYrPA9a16lLRIOcUe9KjBgd
    # RYXRR0IlX5cCVA==
    # SIG # End signature block
    
  • tools\Functions\It.ps1 Show
    function It {
        <#
    .SYNOPSIS
    Validates the results of a test inside of a Describe block.
    
    .DESCRIPTION
    The It command is intended to be used inside of a Describe or Context Block.
    If you are familiar with the AAA pattern (Arrange-Act-Assert), the body of
    the It block is the appropriate location for an assert. The convention is to
    assert a single expectation for each It block. The code inside of the It block
    should throw a terminating error if the expectation of the test is not met and
    thus cause the test to fail. The name of the It block should expressively state
    the expectation of the test.
    
    In addition to using your own logic to test expectations and throw exceptions,
    you may also use Pester's Should command to perform assertions in plain language.
    
    You can intentionally mark It block result as inconclusive by using Set-TestInconclusive
    command as the first tested statement in the It block.
    
    .PARAMETER Name
    An expressive phrase describing the expected test outcome.
    
    .PARAMETER Test
    The script block that should throw an exception if the
    expectation of the test is not met.If you are following the
    AAA pattern (Arrange-Act-Assert), this typically holds the
    Assert.
    
    .PARAMETER Pending
    Use this parameter to explicitly mark the test as work-in-progress/not implemented/pending when you
    need to distinguish a test that fails because it is not finished yet from a tests
    that fail as a result of changes being made in the code base. An empty test, that is a
    test that contains nothing except whitespace or comments is marked as Pending by default.
    
    .PARAMETER Skip
    Use this parameter to explicitly mark the test to be skipped. This is preferable to temporarily
    commenting out a test, because the test remains listed in the output. Use the Strict parameter
    of Invoke-Pester to force all skipped tests to fail.
    
    .PARAMETER TestCases
    Optional array of hashtable (or any IDictionary) objects.  If this parameter is used,
    Pester will call the test script block once for each table in the TestCases array,
    splatting the dictionary to the test script block as input.  If you want the name of
    the test to appear differently for each test case, you can embed tokens into the Name
    parameter with the syntax 'Adds numbers <A> and <B>' (assuming you have keys named A and B
    in your TestCases hashtables.)
    
    .EXAMPLE
    function Add-Numbers($a, $b) {
        return $a + $b
    }
    
    Describe "Add-Numbers" {
        It "adds positive numbers" {
            $sum = Add-Numbers 2 3
            $sum | Should -Be 5
        }
    
        It "adds negative numbers" {
            $sum = Add-Numbers (-2) (-2)
            $sum | Should -Be (-4)
        }
    
        It "adds one negative number to positive number" {
            $sum = Add-Numbers (-2) 2
            $sum | Should -Be 0
        }
    
        It "concatenates strings if given strings" {
            $sum = Add-Numbers two three
            $sum | Should -Be "twothree"
        }
    }
    
    .EXAMPLE
    function Add-Numbers($a, $b) {
        return $a + $b
    }
    
    Describe "Add-Numbers" {
        $testCases = @(
            @{ a = 2;     b = 3;       expectedResult = 5 }
            @{ a = -2;    b = -2;      expectedResult = -4 }
            @{ a = -2;    b = 2;       expectedResult = 0 }
            @{ a = 'two'; b = 'three'; expectedResult = 'twothree' }
        )
    
        It 'Correctly adds <a> and <b> to get <expectedResult>' -TestCases $testCases {
            param ($a, $b, $expectedResult)
    
            $sum = Add-Numbers $a $b
            $sum | Should -Be $expectedResult
        }
    }
    
    .LINK
    https://github.com/pester/Pester/wiki/It
    
    .LINK
    Describe
    Context
    Set-TestInconclusive
    about_should
    #>
        [CmdletBinding(DefaultParameterSetName = 'Normal')]
        param(
            [Parameter(Mandatory = $true, Position = 0)]
            [string] $Name,
    
            [Parameter(Position = 1)]
            [ScriptBlock] $Test = {},
    
            [System.Collections.IDictionary[]] $TestCases,
    
            [Parameter(ParameterSetName = 'Pending')]
            [Switch] $Pending,
    
            [Parameter(ParameterSetName = 'Skip')]
            [Alias('Ignore')]
            [Switch] $Skip
        )
    
        ItImpl -Pester $pester -OutputScriptBlock ${function:Write-PesterResult} @PSBoundParameters
    }
    
    function ItImpl {
        [CmdletBinding(DefaultParameterSetName = 'Normal')]
        param(
            [Parameter(Mandatory = $true, Position = 0)]
            [string]$Name,
    
            [Parameter(Position = 1)]
            [ScriptBlock] $Test,
    
            [System.Collections.IDictionary[]] $TestCases,
            [Parameter(ParameterSetName = 'Pending')]
            [Switch] $Pending,
    
            [Parameter(ParameterSetName = 'Skip')]
            [Alias('Ignore')]
            [Switch] $Skip,
    
            $Pester,
            [scriptblock] $OutputScriptBlock
        )
    
        Assert-DescribeInProgress -CommandName It
    
        # Jumping through hoops to make strict mode happy.
        if ($PSCmdlet.ParameterSetName -ne 'Skip') {
            $Skip = $false
        }
        if ($PSCmdlet.ParameterSetName -ne 'Pending') {
            $Pending = $false
        }
    
        #unless Skip or Pending is specified you must specify a ScriptBlock to the Test parameter
        if (-not ($PSBoundParameters.ContainsKey('test') -or $Skip -or $Pending)) {
            If ($Name.Contains("`n")) {
                throw "Name parameter has multiple lines and no script block is provided. (Have you provided a name for the test group?)"
            }
            else {
                throw 'No test script block is provided. (Have you put the open curly brace on the next line?)'
            }
        }
    
        #the function is called with Pending or Skipped set the script block if needed
        if ($null -eq $Test) {
            $Test = {}
        }
    
        #mark empty Its as Pending
        if ($PSVersionTable.PSVersion.Major -le 2 -and
            $PSCmdlet.ParameterSetName -eq 'Normal' -and
            [String]::IsNullOrEmpty((Remove-Comments $Test.ToString()) -replace "\s")) {
            $Pending = $true
        }
        elseIf ($PSVersionTable.PSVersion.Major -gt 2) {
            #[String]::IsNullOrWhitespace is not available in .NET version used with PowerShell 2
            # AST is not available also
            $testIsEmpty =
            [String]::IsNullOrEmpty($Test.Ast.BeginBlock.Statements) -and
            [String]::IsNullOrEmpty($Test.Ast.ProcessBlock.Statements) -and
            [String]::IsNullOrEmpty($Test.Ast.EndBlock.Statements)
    
            if ($PSCmdlet.ParameterSetName -eq 'Normal' -and $testIsEmpty) {
                $Pending = $true
            }
        }
    
        $pendingSkip = @{}
    
        if ($PSCmdlet.ParameterSetName -eq 'Skip') {
            $pendingSkip['Skip'] = $Skip
        }
        else {
            $pendingSkip['Pending'] = $Pending
        }
    
        if ($null -ne $TestCases -and $TestCases.Count -gt 0) {
            foreach ($testCase in $TestCases) {
                $expandedName = [regex]::Replace($Name, '<([^>]+)>', {
                        $capture = $args[0].Groups[1].Value
                        if ($testCase.Contains($capture)) {
                            $value = $testCase[$capture]
                            # skip adding quotes to non-empty strings to avoid adding junk to the
                            # test name in case you want to expand captures like 'because' or test name
                            if ($value -isnot [string] -or [string]::IsNullOrEmpty($value)) {
                                Format-Nicely $value
                            }
                            else {
                                $value
                            }
                        }
                        else {
                            "<$capture>"
                        }
                    })
    
                $splat = @{
                    Name                   = $expandedName
                    Scriptblock            = $Test
                    Parameters             = $testCase
                    ParameterizedSuiteName = $Name
                    OutputScriptBlock      = $OutputScriptBlock
                }
    
                Invoke-Test @splat @pendingSkip
            }
        }
        else {
            Invoke-Test -Name $Name -ScriptBlock $Test @pendingSkip -OutputScriptBlock $OutputScriptBlock
        }
    }
    
    function Invoke-Test {
        [CmdletBinding(DefaultParameterSetName = 'Normal')]
        param (
            [Parameter(Mandatory = $true)]
            [string] $Name,
    
            [Parameter(Mandatory = $true)]
            [ScriptBlock] $ScriptBlock,
    
            [scriptblock] $OutputScriptBlock,
    
            [System.Collections.IDictionary] $Parameters,
            [string] $ParameterizedSuiteName,
    
            [Parameter(ParameterSetName = 'Pending')]
            [Switch] $Pending,
    
            [Parameter(ParameterSetName = 'Skip')]
            [Alias('Ignore')]
            [Switch] $Skip
        )
    
        if ($null -eq $Parameters) {
            $Parameters = @{}
        }
    
        try {
            if ($Skip) {
                $Pester.AddTestResult($Name, "Skipped", $null)
            }
            elseif ($Pending) {
                $Pester.AddTestResult($Name, "Pending", $null)
            }
            else {
                #todo: disabling the progress for now, it adds a lot of overhead and breaks output on linux, we don't have a good way to disable it by default, or to show it after delay see: https://github.com/pester/Pester/issues/846
                # & $SafeCommands['Write-Progress'] -Activity "Running test '$Name'" -Status Processing
    
                $errorRecord = $null
                try {
                    $pester.EnterTest()
                    Invoke-TestCaseSetupBlocks
    
                    do {
                        Write-ScriptBlockInvocationHint -Hint "It" -ScriptBlock $ScriptBlock
                        $null = & $ScriptBlock @Parameters
                    } until ($true)
                }
                catch {
                    $errorRecord = $_
                }
                finally {
                    #guarantee that the teardown action will run and prevent it from failing the whole suite
                    try {
                        if (-not ($Skip -or $Pending)) {
                            Invoke-TestCaseTeardownBlocks
                        }
                    }
                    catch {
                        $errorRecord = $_
                    }
    
                    $pester.LeaveTest()
                }
    
                $result = ConvertTo-PesterResult -Name $Name -ErrorRecord $errorRecord
                $orderedParameters = Get-OrderedParameterDictionary -ScriptBlock $ScriptBlock -Dictionary $Parameters
                $Pester.AddTestResult( $result.Name, $result.Result, $null, $result.FailureMessage, $result.StackTrace, $ParameterizedSuiteName, $orderedParameters, $result.ErrorRecord )
                #todo: disabling progress reporting see above & $SafeCommands['Write-Progress'] -Activity "Running test '$Name'" -Completed -Status Processing
            }
        }
        finally {
            Exit-MockScope -ExitTestCaseOnly
        }
    
        if ($null -ne $OutputScriptBlock) {
            $Pester.testresult[-1] | & $OutputScriptBlock
        }
    }
    
    function Get-OrderedParameterDictionary {
        [OutputType([System.Collections.IDictionary])]
        param (
            [scriptblock] $ScriptBlock,
            [System.Collections.IDictionary] $Dictionary
        )
    
        $parameters = Get-ParameterDictionary -ScriptBlock $ScriptBlock
    
        $orderedDictionary = & $SafeCommands['New-Object'] System.Collections.Specialized.OrderedDictionary
    
        foreach ($parameterName in $parameters.Keys) {
            $value = $null
            if ($Dictionary.ContainsKey($parameterName)) {
                $value = $Dictionary[$parameterName]
            }
    
            $orderedDictionary[$parameterName] = $value
        }
    
        return $orderedDictionary
    }
    
    function Get-ParameterDictionary {
        param (
            [scriptblock] $ScriptBlock
        )
    
        $guid = [Guid]::NewGuid().Guid
    
        try {
            & $SafeCommands['Set-Content'] function:\$guid $ScriptBlock
            $metadata = [System.Management.Automation.CommandMetadata](& $SafeCommands['Get-Command'] -Name $guid -CommandType Function)
    
            return $metadata.Parameters
        }
        finally {
            if (& $SafeCommands['Test-Path'] function:\$guid) {
                & $SafeCommands['Remove-Item'] function:\$guid
            }
        }
    }
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQU6xdW2NY00Ntd9MhFIf4yCo17
    # GdqggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # wddEdKZtFE3XWEUtKGsFLrXTCaowDQYJKoZIhvcNAQEBBQAEggEAdFbEFawxLiSm
    # 4GymoqelCJ9u5BKah1JJ/9fJh88mrBlWvX371SPihG+l6k88bQgz/G+ey4YoLiwf
    # XKmYQ9c5bSDGpL/ONtBwEBau//kRciaRrexQr5nOpbkK+CXKl56WWjcUdfXOitMg
    # 5+2KRCyIIkiByHZEyGzpqH+IZZJXO/Q91WNhT5j9lo5OjPyLMEtNjRr06X74XDb6
    # 4rDo/C3PIZ2XaWnRtxZhCSiYlHTxJW4f7OPmV8o+1MhLq0FpZ1eZi96EDAccEMn6
    # 4qaG+PuBS5r4IR+EFKm7zHcOfsKe2+QQ1QfFrXBqZvwO6OkXEgcruA2izWFiMJbO
    # Ex/T9W8ieaGCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzQwWjAjBgkqhkiG9w0BCQQx
    # FgQUg56v9G0Yt3wi6McuN0gw7TILkzMwDQYJKoZIhvcNAQEBBQAEggEAFddWkenX
    # bNkZoDbIQY4Uxd0H8FzjXN3PjaaDTobcPa6wKJFYim7jiMH6YqnI1vSZUjnjDbSw
    # rPkF/qlx9qVnqeMeunIpx0TimZm60XEcNpbyx1xmqbuJXiCSc/4jLB5ywI74Imlm
    # fctqxs5q5oVlHpajd50iHVcRwp+J2LNfS+/R+AmiqFcKIR1AKyTsjT+/M3dFKfl3
    # pybBNHoI00U0W8XYtDum/b6aAzl02AWLkYlDOw2axglAu/KtTE2oyMzuvLtWEDYA
    # EH2r2+T+ilNi2QZpcdeJ2NIsfmBM6Yhb5rxwDjLOAaF3VLP9vzj5UzHb1nRRN0MY
    # GtgtMy1gtrerLQ==
    # SIG # End signature block
    
  • tools\Functions\Mock.ps1 Show
    function Mock {
    
        <#
    .SYNOPSIS
    Mocks the behavior of an existing command with an alternate
    implementation.
    
    .DESCRIPTION
    This creates new behavior for any existing command within the scope of a
    Describe or Context block. The function allows you to specify a script block
    that will become the command's new behavior.
    
    Optionally, you may create a Parameter Filter which will examine the
    parameters passed to the mocked command and will invoke the mocked
    behavior only if the values of the parameter values pass the filter. If
    they do not, the original command implementation will be invoked instead
    of a mock.
    
    You may create multiple mocks for the same command, each using a different
    ParameterFilter. ParameterFilters will be evaluated in reverse order of
    their creation. The last one created will be the first to be evaluated.
    The mock of the first filter to pass will be used. The exception to this
    rule are Mocks with no filters. They will always be evaluated last since
    they will act as a "catch all" mock.
    
    Mocks can be marked Verifiable. If so, the Assert-VerifiableMock command
    can be used to check if all Verifiable mocks were actually called. If any
    verifiable mock is not called, Assert-VerifiableMock will throw an
    exception and indicate all mocks not called.
    
    If you wish to mock commands that are called from inside a script module,
    you can do so by using the -ModuleName parameter to the Mock command. This
    injects the mock into the specified module. If you do not specify a
    module name, the mock will be created in the same scope as the test script.
    You may mock the same command multiple times, in different scopes, as needed.
    Each module's mock maintains a separate call history and verified status.
    
    .PARAMETER CommandName
    The name of the command to be mocked.
    
    .PARAMETER MockWith
    A ScriptBlock specifying the behavior that will be used to mock CommandName.
    The default is an empty ScriptBlock.
    NOTE: Do not specify param or dynamicparam blocks in this script block.
    These will be injected automatically based on the signature of the command
    being mocked, and the MockWith script block can contain references to the
    mocked commands parameter variables.
    
    .PARAMETER Verifiable
    When this is set, the mock will be checked when Assert-VerifiableMock is
    called.
    
    .PARAMETER ParameterFilter
    An optional filter to limit mocking behavior only to usages of
    CommandName where the values of the parameters passed to the command
    pass the filter.
    
    This ScriptBlock must return a boolean value. See examples for usage.
    
    .PARAMETER ModuleName
    Optional string specifying the name of the module where this command
    is to be mocked.  This should be a module that _calls_ the mocked
    command; it doesn't necessarily have to be the same module which
    originally implemented the command.
    
    .EXAMPLE
    Mock Get-ChildItem { return @{FullName = "A_File.TXT"} }
    
    Using this Mock, all calls to Get-ChildItem will return a hashtable with a
    FullName property returning "A_File.TXT"
    
    .EXAMPLE
    Mock Get-ChildItem { return @{FullName = "A_File.TXT"} } -ParameterFilter { $Path -and $Path.StartsWith($env:temp) }
    
    This Mock will only be applied to Get-ChildItem calls within the user's temp directory.
    
    .EXAMPLE
    Mock Set-Content {} -Verifiable -ParameterFilter { $Path -eq "some_path" -and $Value -eq "Expected Value" }
    
    When this mock is used, if the Mock is never invoked and Assert-VerifiableMock is called, an exception will be thrown. The command behavior will do nothing since the ScriptBlock is empty.
    
    .EXAMPLE
    Mock Get-ChildItem { return @{FullName = "A_File.TXT"} } -ParameterFilter { $Path -and $Path.StartsWith($env:temp\1) }
    Mock Get-ChildItem { return @{FullName = "B_File.TXT"} } -ParameterFilter { $Path -and $Path.StartsWith($env:temp\2) }
    Mock Get-ChildItem { return @{FullName = "C_File.TXT"} } -ParameterFilter { $Path -and $Path.StartsWith($env:temp\3) }
    
    Multiple mocks of the same command may be used. The parameter filter determines which is invoked. Here, if Get-ChildItem is called on the "2" directory of the temp folder, then B_File.txt will be returned.
    
    .EXAMPLE
    Mock Get-ChildItem { return @{FullName="B_File.TXT"} } -ParameterFilter { $Path -eq "$env:temp\me" }
    Mock Get-ChildItem { return @{FullName="A_File.TXT"} } -ParameterFilter { $Path -and $Path.StartsWith($env:temp) }
    
    Get-ChildItem $env:temp\me
    
    Here, both mocks could apply since both filters will pass. A_File.TXT will be returned because it was the most recent Mock created.
    
    .EXAMPLE
    Mock Get-ChildItem { return @{FullName = "B_File.TXT"} } -ParameterFilter { $Path -eq "$env:temp\me" }
    Mock Get-ChildItem { return @{FullName = "A_File.TXT"} }
    
    Get-ChildItem c:\windows
    
    Here, A_File.TXT will be returned. Since no filter was specified, it will apply to any call to Get-ChildItem that does not pass another filter.
    
    .EXAMPLE
    Mock Get-ChildItem { return @{FullName = "B_File.TXT"} } -ParameterFilter { $Path -eq "$env:temp\me" }
    Mock Get-ChildItem { return @{FullName = "A_File.TXT"} }
    
    Get-ChildItem $env:temp\me
    
    Here, B_File.TXT will be returned. Even though the filterless mock was created more recently. This illustrates that filterless Mocks are always evaluated last regardless of their creation order.
    
    .EXAMPLE
    Mock Get-ChildItem { return @{FullName = "A_File.TXT"} } -ModuleName MyTestModule
    
    Using this Mock, all calls to Get-ChildItem from within the MyTestModule module
    will return a hashtable with a FullName property returning "A_File.TXT"
    
    .EXAMPLE
    Get-Module -Name ModuleMockExample | Remove-Module
    New-Module -Name ModuleMockExample  -ScriptBlock {
        function Hidden { "Internal Module Function" }
        function Exported { Hidden }
    
        Export-ModuleMember -Function Exported
    } | Import-Module -Force
    
    Describe "ModuleMockExample" {
    
        It "Hidden function is not directly accessible outside the module" {
            { Hidden } | Should -Throw
        }
    
        It "Original Hidden function is called" {
            Exported | Should -Be "Internal Module Function"
        }
    
        It "Hidden is replaced with our implementation" {
            Mock Hidden { "Mocked" } -ModuleName ModuleMockExample
            Exported | Should -Be "Mocked"
        }
    }
    
    This example shows how calls to commands made from inside a module can be
    mocked by using the -ModuleName parameter.
    
    
    .LINK
    Assert-MockCalled
    Assert-VerifiableMock
    Describe
    Context
    It
    about_Should
    about_Mocking
    #>
        [CmdletBinding()]
        param(
            [string]$CommandName,
            [ScriptBlock]$MockWith = {},
            [switch]$Verifiable,
            [ScriptBlock]$ParameterFilter = {$True},
            [string]$ModuleName
        )
    
        Assert-DescribeInProgress -CommandName Mock
        Set-ScriptBlockHint -Hint "Unbound MockWith - Captured in Mock" -ScriptBlock $MockWith
        Set-ScriptBlockHint -Hint "Unbound ParameterFilter - Captured in Mock" -ScriptBlock $ParameterFilter
    
        $contextInfo = Validate-Command $CommandName $ModuleName
        $CommandName = $contextInfo.Command.Name
    
        if ($contextInfo.Session.Module -and $contextInfo.Session.Module.Name) {
            $ModuleName = $contextInfo.Session.Module.Name
        }
        else {
            $ModuleName = ''
        }
    
        if (Test-IsClosure -ScriptBlock $MockWith) {
            # If the user went out of their way to call GetNewClosure(), go ahead and leave the block bound to that
            # dynamic module's scope.
            $mockWithCopy = $MockWith
        }
        else {
            Write-Hint "Unbinding ScriptBlock from '$(Get-ScriptBlockHint $MockWith)'"
            $mockWithCopy = [scriptblock]::Create($MockWith.ToString())
            Set-ScriptBlockHint -ScriptBlock $mockWithCopy -Hint "Unbound ScriptBlock from Mock"
            Set-ScriptBlockScope -ScriptBlock $mockWithCopy -SessionState $contextInfo.Session
        }
    
        $block = @{
            Mock       = $mockWithCopy
            Filter     = $ParameterFilter
            Verifiable = $Verifiable
            Scope      = $pester.CurrentTestGroup
        }
    
        $mock = $mockTable["$ModuleName||$CommandName"]
    
        if (-not $mock) {
            $metadata = $null
            $cmdletBinding = ''
            $paramBlock = ''
            $dynamicParamBlock = ''
            $dynamicParamScriptBlock = $null
    
            if ($contextInfo.Command.psobject.Properties['ScriptBlock'] -or $contextInfo.Command.CommandType -eq 'Cmdlet') {
                $metadata = [System.Management.Automation.CommandMetaData]$contextInfo.Command
                $null = $metadata.Parameters.Remove('Verbose')
                $null = $metadata.Parameters.Remove('Debug')
                $null = $metadata.Parameters.Remove('ErrorAction')
                $null = $metadata.Parameters.Remove('WarningAction')
                $null = $metadata.Parameters.Remove('ErrorVariable')
                $null = $metadata.Parameters.Remove('WarningVariable')
                $null = $metadata.Parameters.Remove('OutVariable')
                $null = $metadata.Parameters.Remove('OutBuffer')
    
                # Some versions of PowerShell may include dynamic parameters here
                # We will filter them out and add them at the end to be
                # compatible with both earlier and later versions
                $dynamicParams = $metadata.Parameters.Values | & $SafeCommands['Where-Object'] {$_.IsDynamic}
                if ($null -ne $dynamicParams) {
                    $dynamicparams | & $SafeCommands['ForEach-Object'] { $null = $metadata.Parameters.Remove($_.name) }
                }
    
                $cmdletBinding = [Management.Automation.ProxyCommand]::GetCmdletBindingAttribute($metadata)
                if ($global:PSVersionTable.PSVersion.Major -ge 3 -and $contextInfo.Command.CommandType -eq 'Cmdlet') {
                    if ($cmdletBinding -ne '[CmdletBinding()]') {
                        $cmdletBinding = $cmdletBinding.Insert($cmdletBinding.Length - 2, ',')
                    }
                    $cmdletBinding = $cmdletBinding.Insert($cmdletBinding.Length - 2, 'PositionalBinding=$false')
                }
    
                # Will modify $metadata object in-place
                Repair-ConflictingParameters -Metadata $metadata
                $paramBlock = [Management.Automation.ProxyCommand]::GetParamBlock($metadata)
    
                if ($contextInfo.Command.CommandType -eq 'Cmdlet') {
                    $dynamicParamBlock = "dynamicparam { Get-MockDynamicParameter -CmdletName '$($contextInfo.Command.Name)' -Parameters `$PSBoundParameters }"
                }
                else {
                    $dynamicParamStatements = Get-DynamicParamBlock -ScriptBlock $contextInfo.Command.ScriptBlock
    
                    if ($dynamicParamStatements -match '\S') {
                        $metadataSafeForDynamicParams = [System.Management.Automation.CommandMetaData]$contextInfo.Command
                        foreach ($param in $metadataSafeForDynamicParams.Parameters.Values) {
                            $param.ParameterSets.Clear()
                        }
    
                        $paramBlockSafeForDynamicParams = [System.Management.Automation.ProxyCommand]::GetParamBlock($metadataSafeForDynamicParams)
                        $comma = if ($metadataSafeForDynamicParams.Parameters.Count -gt 0) {
                            ','
                        }
                        else {
                            ''
                        }
                        $dynamicParamBlock = "dynamicparam { Get-MockDynamicParameter -ModuleName '$ModuleName' -FunctionName '$CommandName' -Parameters `$PSBoundParameters -Cmdlet `$PSCmdlet }"
    
                        $code = @"
                            $cmdletBinding
                            param(
                                [object] `${P S Cmdlet}$comma
                                $paramBlockSafeForDynamicParams
                            )
    
                            `$PSCmdlet = `${P S Cmdlet}
    
                            $dynamicParamStatements
    "@
    
                        $dynamicParamScriptBlock = [scriptblock]::Create($code)
    
                        $sessionStateInternal = Get-ScriptBlockScope -ScriptBlock $contextInfo.Command.ScriptBlock
    
                        if ($null -ne $sessionStateInternal) {
                            Set-ScriptBlockScope -ScriptBlock $dynamicParamScriptBlock -SessionStateInternal $sessionStateInternal
                        }
                    }
                }
            }
    
            $EscapeSingleQuotedStringContent =
            if ($global:PSVersionTable.PSVersion.Major -ge 5) {
                { [System.Management.Automation.Language.CodeGeneration]::EscapeSingleQuotedStringContent($args[0]) }
            }
            else {
                { $args[0] -replace "['‘’‚‛]", '$&$&' }
            }
    
            $newContent = & $SafeCommands['Get-Content'] function:\MockPrototype
            $newContent = $newContent -replace '#FUNCTIONNAME#', (& $EscapeSingleQuotedStringContent $CommandName)
            $newContent = $newContent -replace '#MODULENAME#', (& $EscapeSingleQuotedStringContent $ModuleName)
    
            $canCaptureArgs = 'true'
            if ($contextInfo.Command.CommandType -eq 'Cmdlet' -or
                ($contextInfo.Command.CommandType -eq 'Function' -and $contextInfo.Command.CmdletBinding)) {
                $canCaptureArgs = 'false'
            }
            $newContent = $newContent -replace '#CANCAPTUREARGS#', $canCaptureArgs
    
            $code = @"
                $cmdletBinding
                param ( $paramBlock )
                $dynamicParamBlock
                begin
                {
                    `${mock call state} = @{}
                    $($newContent -replace '#BLOCK#', 'Begin' -replace '#INPUT#')
                }
    
                process
                {
                    $($newContent -replace '#BLOCK#', 'Process' -replace '#INPUT#', '-InputObject @($input)')
                }
    
                end
                {
                    $($newContent -replace '#BLOCK#', 'End' -replace '#INPUT#')
                }
    "@
    
            $mockScript = [scriptblock]::Create($code)
    
            $mock = @{
                OriginalCommand         = $contextInfo.Command
                Blocks                  = @()
                CommandName             = $CommandName
                SessionState            = $contextInfo.Session
                Scope                   = $pester.CurrentTestGroup
                PesterState             = $pester
                Metadata                = $metadata
                CallHistory             = @()
                DynamicParamScriptBlock = $dynamicParamScriptBlock
                Aliases                 = @()
                BootstrapFunctionName   = 'PesterMock_' + [Guid]::NewGuid().Guid
            }
    
            $mockTable["$ModuleName||$CommandName"] = $mock
    
            Invoke-CommonSetupInMockScope -Mock $mock -MockScript $MockScript -CommandName $CommandName
        }
    
        if ($null -ne $mock.Metadata -and $null -ne $block.Filter) {
            $block.Filter = New-BlockWithoutParameterAliases -Metadata $mock.Metadata -Block $block.Filter
        }
    
        $mock.Blocks = @(
            $mock.Blocks | & $SafeCommands['Where-Object'] { $_.Filter.ToString() -eq '$True' }
            if ($block.Filter.ToString() -eq '$True') {
                $block
            }
    
            $mock.Blocks | & $SafeCommands['Where-Object'] { $_.Filter.ToString() -ne '$True' }
            if ($block.Filter.ToString() -ne '$True') {
                $block
            }
        )
    }
    
    
    function Assert-VerifiableMock {
        <#
    .SYNOPSIS
    Checks if any Verifiable Mock has not been invoked. If so, this will throw an exception.
    
    .DESCRIPTION
    This can be used in tandem with the -Verifiable switch of the Mock
    function. Mock can be used to mock the behavior of an existing command
    and optionally take a -Verifiable switch. When Assert-VerifiableMock
    is called, it checks to see if any Mock marked Verifiable has not been
    invoked. If any mocks have been found that specified -Verifiable and
    have not been invoked, an exception will be thrown.
    
    .EXAMPLE
    Mock Set-Content {} -Verifiable -ParameterFilter {$Path -eq "some_path" -and $Value -eq "Expected Value"}
    
    { ...some code that never calls Set-Content some_path -Value "Expected Value"... }
    
    Assert-VerifiableMock
    
    This will throw an exception and cause the test to fail.
    
    .EXAMPLE
    Mock Set-Content {} -Verifiable -ParameterFilter {$Path -eq "some_path" -and $Value -eq "Expected Value"}
    
    Set-Content some_path -Value "Expected Value"
    
    Assert-VerifiableMock
    
    This will not throw an exception because the mock was invoked.
    
    #>
        [CmdletBinding()]param()
        Assert-DescribeInProgress -CommandName Assert-VerifiableMock
    
        $unVerified = @{}
        $mockTable.Keys | & $SafeCommands['ForEach-Object'] {
            $m = $_;
    
            $mockTable[$m].blocks |
                & $SafeCommands['Where-Object'] { $_.Verifiable } |
                & $SafeCommands['ForEach-Object'] { $unVerified[$m] = $_ }
        }
        if ($unVerified.Count -gt 0) {
            foreach ($mock in $unVerified.Keys) {
                $array = $mock -split '\|\|'
                $function = $array[1]
                $module = $array[0]
    
                $message = "$([System.Environment]::NewLine) Expected $function "
                if ($module) {
                    $message += "in module $module "
                }
                $message += "to be called with $($unVerified[$mock].Filter)"
            }
            throw $message
        }
    }
    
    function Assert-MockCalled {
        <#
    .SYNOPSIS
    Checks if a Mocked command has been called a certain number of times
    and throws an exception if it has not.
    
    .DESCRIPTION
    This command verifies that a mocked command has been called a certain number
    of times.  If the call history of the mocked command does not match the parameters
    passed to Assert-MockCalled, Assert-MockCalled will throw an exception.
    
    .PARAMETER CommandName
    The mocked command whose call history should be checked.
    
    .PARAMETER ModuleName
    The module where the mock being checked was injected.  This is optional,
    and must match the ModuleName that was used when setting up the Mock.
    
    .PARAMETER Times
    The number of times that the mock must be called to avoid an exception
    from throwing.
    
    .PARAMETER Exactly
    If this switch is present, the number specified in Times must match
    exactly the number of times the mock has been called. Otherwise it
    must match "at least" the number of times specified.  If the value
    passed to the Times parameter is zero, the Exactly switch is implied.
    
    .PARAMETER ParameterFilter
    An optional filter to qualify which calls should be counted. Only those
    calls to the mock whose parameters cause this filter to return true
    will be counted.
    
    .PARAMETER ExclusiveFilter
    Like ParameterFilter, except when you use ExclusiveFilter, and there
    were any calls to the mocked command which do not match the filter,
    an exception will be thrown.  This is a convenient way to avoid needing
    to have two calls to Assert-MockCalled like this:
    
    Assert-MockCalled SomeCommand -Times 1 -ParameterFilter { $something -eq $true }
    Assert-MockCalled SomeCommand -Times 0 -ParameterFilter { $something -ne $true }
    
    .PARAMETER Scope
    An optional parameter specifying the Pester scope in which to check for
    calls to the mocked command. For RSpec style tests, Assert-MockCalled will find
    all calls to the mocked command in the current Context block (if present),
    or the current Describe block (if there is no active Context), by default. Valid
    values are Describe, Context and It. If you use a scope of Describe or
    Context, the command will identify all calls to the mocked command in the
    current Describe / Context block, as well as all child scopes of that block.
    
    For Gherkin style tests, Assert-MockCalled will find all calls to the mocked
    command in the current Scenario block or the current Feature block (if there is
    no active Scenario), by default. Valid values for Gherkin style tests are Feature
    and Scenario. If you use a scope of Feature or Scenario, the command will identify
    all calls to the mocked command in the current Feature / Scenario block, as well
    as all child scopes of that block.
    
    .EXAMPLE
    C:\PS>Mock Set-Content {}
    
    {... Some Code ...}
    
    C:\PS>Assert-MockCalled Set-Content
    
    This will throw an exception and cause the test to fail if Set-Content is not called in Some Code.
    
    .EXAMPLE
    C:\PS>Mock Set-Content -parameterFilter {$path.StartsWith("$env:temp\")}
    
    {... Some Code ...}
    
    C:\PS>Assert-MockCalled Set-Content 2 { $path -eq "$env:temp\test.txt" }
    
    This will throw an exception if some code calls Set-Content on $path=$env:temp\test.txt less than 2 times
    
    .EXAMPLE
    C:\PS>Mock Set-Content {}
    
    {... Some Code ...}
    
    C:\PS>Assert-MockCalled Set-Content 0
    
    This will throw an exception if some code calls Set-Content at all
    
    .EXAMPLE
    C:\PS>Mock Set-Content {}
    
    {... Some Code ...}
    
    C:\PS>Assert-MockCalled Set-Content -Exactly 2
    
    This will throw an exception if some code does not call Set-Content Exactly two times.
    
    .EXAMPLE
    Describe 'Assert-MockCalled Scope behavior' {
        Mock Set-Content { }
    
        It 'Calls Set-Content at least once in the It block' {
            {... Some Code ...}
    
            Assert-MockCalled Set-Content -Exactly 0 -Scope It
        }
    }
    
    Checks for calls only within the current It block.
    
    .EXAMPLE
    Describe 'Describe' {
        Mock -ModuleName SomeModule Set-Content { }
    
        {... Some Code ...}
    
        It 'Calls Set-Content at least once in the Describe block' {
            Assert-MockCalled -ModuleName SomeModule Set-Content
        }
    }
    
    Checks for calls to the mock within the SomeModule module.  Note that both the Mock
    and Assert-MockCalled commands use the same module name.
    
    .EXAMPLE
    Assert-MockCalled Get-ChildItem -ExclusiveFilter { $Path -eq 'C:\' }
    
    Checks to make sure that Get-ChildItem was called at least one time with
    the -Path parameter set to 'C:\', and that it was not called at all with
    the -Path parameter set to any other value.
    
    .NOTES
    The parameter filter passed to Assert-MockCalled does not necessarily have to match the parameter filter
    (if any) which was used to create the Mock.  Assert-MockCalled will find any entry in the command history
    which matches its parameter filter, regardless of how the Mock was created.  However, if any calls to the
    mocked command are made which did not match any mock's parameter filter (resulting in the original command
    being executed instead of a mock), these calls to the original command are not tracked in the call history.
    In other words, Assert-MockCalled can only be used to check for calls to the mocked implementation, not
    to the original.
    
    #>
    
        [CmdletBinding(DefaultParameterSetName = 'ParameterFilter')]
        param(
            [Parameter(Mandatory = $true, Position = 0)]
            [string]$CommandName,
    
            [Parameter(Position = 1)]
            [int]$Times = 1,
    
            [Parameter(ParameterSetName = 'ParameterFilter', Position = 2)]
            [ScriptBlock]$ParameterFilter = {$True},
    
            [Parameter(ParameterSetName = 'ExclusiveFilter', Mandatory = $true)]
            [scriptblock] $ExclusiveFilter,
    
            [Parameter(Position = 3)]
            [string] $ModuleName,
    
            [Parameter(Position = 4)]
            [ValidateScript( {
                    if ([uint32]::TryParse($_, [ref] $null) -or
                        $_ -eq 'Describe' -or
                        $_ -eq 'Context' -or
                        $_ -eq 'It' -or
                        $_ -eq 'Feature' -or
                        $_ -eq 'Scenario') {
                        return $true
                    }
    
                    throw "Scope argument must either be an unsigned integer, or one of the words 'Describe', 'Context', 'It', 'Feature', or 'Scenario'."
                })]
            [string] $Scope,
    
            [switch]$Exactly
        )
    
        if ($PSCmdlet.ParameterSetName -eq 'ParameterFilter') {
            $filter = $ParameterFilter
            $filterIsExclusive = $false
        }
        else {
            $filter = $ExclusiveFilter
            $filterIsExclusive = $true
        }
    
        Assert-DescribeInProgress -CommandName Assert-MockCalled
    
        if (-not $PSBoundParameters.ContainsKey('ModuleName') -and $null -ne $pester.SessionState.Module) {
            $ModuleName = $pester.SessionState.Module.Name
        }
    
        $contextInfo = Validate-Command $CommandName $ModuleName
        $CommandName = $contextInfo.Command.Name
    
        $mock = $script:mockTable["$ModuleName||$CommandName"]
    
        $moduleMessage = ''
        if ($ModuleName) {
            $moduleMessage = " in module $ModuleName"
        }
    
        if (-not $mock) {
            throw "You did not declare a mock of the $commandName Command${moduleMessage}."
        }
    
        if (-not $PSBoundParameters.ContainsKey('Scope')) {
            $scope = 1
        }
    
        $matchingCalls = & $SafeCommands['New-Object'] System.Collections.ArrayList
        $nonMatchingCalls = & $SafeCommands['New-Object'] System.Collections.ArrayList
    
        foreach ($historyEntry in $mock.CallHistory) {
            if (-not (Test-MockCallScope -CallScope $historyEntry.Scope -DesiredScope $Scope)) {
                continue
            }
    
            $params = @{
                ScriptBlock     = $filter
                BoundParameters = $historyEntry.BoundParams
                ArgumentList    = $historyEntry.Args
                Metadata        = $mock.Metadata
            }
    
            if ($null -ne $mock.Metadata -and $null -ne $params.ScriptBlock) {
                $params.ScriptBlock = New-BlockWithoutParameterAliases -Metadata $mock.Metadata -Block $params.ScriptBlock
            }
    
            if (Test-ParameterFilter @params) {
                $null = $matchingCalls.Add($historyEntry)
            }
            else {
                $null = $nonMatchingCalls.Add($historyEntry)
            }
        }
    
        $lineText = $MyInvocation.Line.TrimEnd("$([System.Environment]::NewLine)")
        $line = $MyInvocation.ScriptLineNumber
    
        if ($matchingCalls.Count -ne $times -and ($Exactly -or ($times -eq 0))) {
            $failureMessage = "Expected ${commandName}${moduleMessage} to be called $times times exactly but was called $($matchingCalls.Count) times"
            throw ( New-ShouldErrorRecord -Message $failureMessage -Line $line -LineText $lineText)
        }
        elseif ($matchingCalls.Count -lt $times) {
            $failureMessage = "Expected ${commandName}${moduleMessage} to be called at least $times times but was called $($matchingCalls.Count) times"
            throw ( New-ShouldErrorRecord -Message $failureMessage -Line $line -LineText $lineText)
        }
        elseif ($filterIsExclusive -and $nonMatchingCalls.Count -gt 0) {
            $failureMessage = "Expected ${commandName}${moduleMessage} to only be called with with parameters matching the specified filter, but $($nonMatchingCalls.Count) non-matching calls were made"
            throw ( New-ShouldErrorRecord -Message $failureMessage -Line $line -LineText $lineText)
        }
    }
    
    function Test-MockCallScope {
        [CmdletBinding()]
        param (
            [object] $CallScope,
            [string] $DesiredScope
        )
    
        if ($null -eq $CallScope) {
            # This indicates a call from the current test case ("It" block), which always passes Test-MockCallScope
            return $true
        }
    
        $testGroups = $pester.TestGroups
        [Array]::Reverse($testGroups)
    
        $target = 0
        $isNumberedScope = [int]::TryParse($DesiredScope, [ref] $target)
    
        # The Describe / Context stuff here is for backward compatibility.  May be deprecated / removed in the future.
        $actualScopeNumber = -1
        $describe = -1
        $context = -1
    
        for ($i = 0; $i -lt $testGroups.Count; $i++) {
            if ($CallScope -eq $testGroups[$i]) {
                $actualScopeNumber = $i
                if ($isNumberedScope) {
                    break
                }
            }
    
            if ($describe -lt 0 -and 'Describe', 'Feature' -contains $testGroups[$i].Hint) {
                $describe = $i
            }
            if ($context -lt 0 -and 'Context', 'Scenario' -contains $testGroups[$i].Hint) {
                $context = $i
            }
        }
    
        if ($actualScopeNumber -lt 0) {
            # this should never happen; if we get here, it's a Pester bug.
    
            throw "Pester error: Corrupted mock call history table."
        }
    
        if ($isNumberedScope) {
            # For this, we consider scope 0 to be the current test case / It block, scope 1 to be the first Test Group up the stack, etc.
            # $actualScopeNumber currently off by one from that scale (zero-indexed for test groups only; we already checked for the 0 case
            # farther up, which only applies if $CallScope is $null).
            return $target -gt $actualScopeNumber
        }
        else {
            if ('Describe', 'Feature' -contains $DesiredScope) {
                return $describe -ge $actualScopeNumber
            }
            if ('Context', 'Scenario' -contains $DesiredScope) {
                return $context -ge $actualScopeNumber
            }
        }
    
        return $false
    }
    
    function Exit-MockScope {
        param (
            [switch] $ExitTestCaseOnly
        )
    
        if ($null -eq $mockTable) {
            return
        }
    
        $removeMockStub =
        {
            param (
                [string] $CommandName,
                [string[]] $Aliases
            )
    
            $ExecutionContext.InvokeProvider.Item.Remove("Function:\$CommandName", $false, $true, $true)
    
            foreach ($alias in $Aliases) {
                if ($ExecutionContext.InvokeProvider.Item.Exists("Alias:$alias", $true, $true)) {
                    $ExecutionContext.InvokeProvider.Item.Remove("Alias:$alias", $false, $true, $true)
                }
            }
        }
    
        $mockKeys = [string[]]$mockTable.Keys
    
        foreach ($mockKey in $mockKeys) {
            $mock = $mockTable[$mockKey]
    
            $shouldRemoveMock = (-not $ExitTestCaseOnly) -and (ShouldRemoveMock -Mock $mock -ActivePesterState $pester)
            if ($shouldRemoveMock) {
                $null = Invoke-InMockScope -SessionState $mock.SessionState -ScriptBlock $removeMockStub -ArgumentList $mock.BootstrapFunctionName, $mock.Aliases
                $mockTable.Remove($mockKey)
            }
            elseif ($mock.PesterState -eq $pester) {
                if (-not $ExitTestCaseOnly) {
                    $mock.Blocks = @($mock.Blocks | & $SafeCommands['Where-Object'] { $_.Scope -ne $pester.CurrentTestGroup })
                }
    
                $testGroups = @($pester.TestGroups)
    
                $parentTestGroup = $null
    
                if ($testGroups.Count -gt 1) {
                    $parentTestGroup = $testGroups[-2]
                }
    
                foreach ($historyEntry in $mock.CallHistory) {
                    if ($ExitTestCaseOnly) {
                        if ($null -eq $historyEntry.Scope) {
                            $historyEntry.Scope = $pester.CurrentTestGroup
                        }
                    }
                    elseif ($parentTestGroup) {
                        if ($historyEntry.Scope -eq $pester.CurrentTestGroup) {
                            $historyEntry.Scope = $parentTestGroup
                        }
                    }
                }
            }
        }
    }
    
    function ShouldRemoveMock($Mock, $ActivePesterState) {
        if ($ActivePesterState -ne $mock.PesterState) {
            return $false
        }
        if ($mock.Scope -eq $ActivePesterState.CurrentTestGroup) {
            return $true
        }
    
        # These two should conditions should _probably_ never happen, because the above condition should
        # catch it, but just in case:
        if ($ActivePesterState.TestGroups.Count -eq 1) {
            return $true
        }
        if ($ActivePesterState.TestGroups[-2].Hint -eq 'Root') {
            return $true
        }
    
        return $false
    }
    
    function Validate-Command([string]$CommandName, [string]$ModuleName) {
        $module = $null
        $command = $null
    
        $scriptBlock = {
            $command = $ExecutionContext.InvokeCommand.GetCommand($args[0], 'All')
            while ($null -ne $command -and $command.CommandType -eq [System.Management.Automation.CommandTypes]::Alias) {
                $command = $command.ResolvedCommand
            }
    
            return $command
        }
    
        if ($ModuleName) {
            $module = Get-ScriptModule -ModuleName $ModuleName -ErrorAction Stop
            $command = & $module $scriptBlock $CommandName
        }
    
        $session = $pester.SessionState
    
        if (-not $command) {
            Set-ScriptBlockScope -ScriptBlock $scriptBlock -SessionState $session
            $command = & $scriptBlock $commandName
        }
    
        if (-not $command) {
            throw ([System.Management.Automation.CommandNotFoundException] "Could not find Command $commandName")
        }
    
        if ($module) {
            $session = Set-SessionStateHint -PassThru  -Hint "Module - $($module.Name)" -SessionState ( & $module { $ExecutionContext.SessionState } )
        }
    
        $hash = @{Command = $command; Session = $session}
    
        if ($command.CommandType -eq 'Function') {
            foreach ($mock in $mockTable.Values) {
                if ($command.Name -eq $mock.BootstrapFunctionName) {
                    return @{
                        Command = $mock.OriginalCommand
                        Session = $mock.SessionState
                    }
                }
            }
        }
    
        return $hash
    }
    
    function MockPrototype {
        if ($PSVersionTable.PSVersion.Major -ge 3) {
            [string] ${ignore preference} = 'Ignore'
        }
        else {
            [string] ${ignore preference} = 'SilentlyContinue'
        }
    
        #todo: remove pester\safegetcommand and use .net calls to get the variable instead?
        ${get Variable Command} = & (Pester\SafeGetCommand) -Name Get-Variable -Module Microsoft.PowerShell.Utility -CommandType Cmdlet
    
        [object] ${a r g s} = $null
        if (${#CANCAPTUREARGS#}) {
            ${a r g s} = & ${get Variable Command} -Name args -ValueOnly -Scope Local -ErrorAction ${ignore preference}
        }
        if ($null -eq ${a r g s}) {
            ${a r g s} = @()
        }
    
        ${p s cmdlet} = & ${get Variable Command} -Name PSCmdlet -ValueOnly -Scope Local -ErrorAction ${ignore preference}
    
        #todo: Add session state hint - once we are calling this in the Pester state
        ${session state} = if (${p s cmdlet}) {
            ${p s cmdlet}.SessionState
        }
    
        # todo: lookup Pester state and invoke it in there to remote Invoke-Mock from the public Api
        # @{mock call state} initialization is injected only into the begin block by the code that uses this prototype.
        Invoke-Mock -CommandName '#FUNCTIONNAME#' -ModuleName '#MODULENAME#' -BoundParameters $PSBoundParameters -ArgumentList ${a r g s} -CallerSessionState ${session state} -FromBlock '#BLOCK#' -MockCallState ${mock call state} #INPUT#
    }
    
    function Invoke-Mock {
        <#
            .SYNOPSIS
            This command is used by Pester's Mocking framework.  You do not need to call it directly.
        #>
    
        [CmdletBinding()]
        param (
            [Parameter(Mandatory = $true)]
            [string]
            $CommandName,
    
            [Parameter(Mandatory = $true)]
            [hashtable] $MockCallState,
    
            [string]
            $ModuleName,
    
            [hashtable]
            $BoundParameters = @{},
    
            [object[]]
            $ArgumentList = @(),
    
            [object] $CallerSessionState,
    
            [ValidateSet('Begin', 'Process', 'End')]
            [string] $FromBlock,
    
            [object] $InputObject
        )
    
        $detectedModule = $ModuleName
        $mock = FindMock -CommandName $CommandName -ModuleName ([ref]$detectedModule)
    
        if ($null -eq $mock) {
            # If this ever happens, it's a bug in Pester.  The scriptBlock that calls Invoke-Mock should be removed at the same time as the entry in the mock table.
            throw "Internal error detected:  Mock for '$CommandName' in module '$ModuleName' was called, but does not exist in the mock table."
        }
    
        switch ($FromBlock) {
            Begin {
                $MockCallState['InputObjects'] = & $SafeCommands['New-Object'] System.Collections.ArrayList
                $MockCallState['ShouldExecuteOriginalCommand'] = $false
                $MockCallState['BeginBoundParameters'] = $BoundParameters.Clone()
                $MockCallState['BeginArgumentList'] = $ArgumentList
    
                return
            }
    
            Process {
                $block = $null
                if ($detectedModule -eq $ModuleName) {
                    $block = FindMatchingBlock -Mock $mock -BoundParameters $BoundParameters -ArgumentList $ArgumentList
                }
    
                if ($null -ne $block) {
                    ExecuteBlock -Block $block `
                        -CommandName $CommandName `
                        -ModuleName $ModuleName `
                        -BoundParameters $BoundParameters `
                        -ArgumentList $ArgumentList `
                        -Mock $mock
    
                    return
                }
                else {
                    $MockCallState['ShouldExecuteOriginalCommand'] = $true
                    if ($null -ne $InputObject) {
                        $null = $MockCallState['InputObjects'].AddRange(@($InputObject))
                    }
    
                    return
                }
            }
    
            End {
                if ($MockCallState['ShouldExecuteOriginalCommand']) {
                    $MockCallState['BeginBoundParameters'] = Reset-ConflictingParameters -BoundParameters $MockCallState['BeginBoundParameters']
    
                    if ($MockCallState['InputObjects'].Count -gt 0) {
                        $scriptBlock = {
                            param ($Command, $ArgumentList, $BoundParameters, $InputObjects)
                            $InputObjects | & $Command @ArgumentList @BoundParameters
                        }
                    }
                    else {
                        $scriptBlock = {
                            param ($Command, $ArgumentList, $BoundParameters, $InputObjects)
                            & $Command @ArgumentList @BoundParameters
                        }
                    }
    
                    $state = if ($CallerSessionState) {
                        $CallerSessionState
                    }
                    else {
                        $mock.SessionState
                    }
    
                    Set-ScriptBlockScope -ScriptBlock $scriptBlock -SessionState $state
    
                    # In order to mock Set-Variable correctly we need to write the variable
                    # two scopes above
                    if ( $mock.OriginalCommand -like "Set-Variable" ) {
                        if ($MockCallState['BeginBoundParameters'].Keys -notcontains "Scope") {
                            $MockCallState['BeginBoundParameters'].Add( "Scope", 2)
                        }
                        # local is the same as scope 0, in that case we also write to scope 2
                        elseif ("Local", "0" -contains $MockCallState['BeginBoundParameters'].Scope) {
                            $MockCallState['BeginBoundParameters'].Scope = 2
                        }
                        elseif ($MockCallState['BeginBoundParameters'].Scope -match "\d+") {
                            $MockCallState['BeginBoundParameters'].Scope = 2 + $matches[0]
                        }
                        else {
                            # not sure what the user did, but we won't change it
                        }
                    }
    
                    Write-ScriptBlockInvocationHint -Hint "Mock - Original Command" -ScriptBlock $scriptBlock
                    & $scriptBlock -Command $mock.OriginalCommand `
                        -ArgumentList $MockCallState['BeginArgumentList'] `
                        -BoundParameters $MockCallState['BeginBoundParameters'] `
                        -InputObjects $MockCallState['InputObjects']
                }
            }
        }
    }
    
    function FindMock {
        param (
            [string] $CommandName,
            [ref] $ModuleName
        )
    
        $mock = $mockTable["$($ModuleName.Value)||$CommandName"]
    
        if ($null -eq $mock) {
            $mock = $mockTable["||$CommandName"]
            if ($null -ne $mock) {
                $ModuleName.Value = ''
            }
        }
    
        return $mock
    }
    
    function FindMatchingBlock {
        param (
            [object] $Mock,
            [hashtable] $BoundParameters = @{},
            [object[]] $ArgumentList = @()
        )
    
        for ($idx = $mock.Blocks.Length; $idx -gt 0; $idx--) {
            $block = $mock.Blocks[$idx - 1]
    
            $params = @{
                ScriptBlock     = $block.Filter
                BoundParameters = $BoundParameters
                ArgumentList    = $ArgumentList
                Metadata        = $mock.Metadata
            }
    
            if (Test-ParameterFilter @params) {
                return $block
            }
        }
    
        return $null
    }
    
    function ExecuteBlock {
        param (
            [object] $Block,
            [object] $Mock,
            [string] $CommandName,
            [string] $ModuleName,
            [hashtable] $BoundParameters = @{},
            [object[]] $ArgumentList = @()
        )
    
        $Block.Verifiable = $false
    
        $scope = if ($pester.InTest) {
            $null
        }
        else {
            $pester.CurrentTestGroup
        }
        $Mock.CallHistory += @{CommandName = "$ModuleName||$CommandName"; BoundParams = $BoundParameters; Args = $ArgumentList; Scope = $scope }
    
        $scriptBlock = {
            param (
                [Parameter(Mandatory = $true)]
                [scriptblock]
                ${Script Block},
    
                [hashtable]
                $___BoundParameters___ = @{},
    
                [object[]]
                $___ArgumentList___ = @(),
    
                [System.Management.Automation.CommandMetadata]
                ${Meta data},
    
                [System.Management.Automation.SessionState]
                ${Session State},
    
                ${R e p o r t S c o p e},
    
                ${M o d u l e N a m e}
            )
    
            # This script block exists to hold variables without polluting the test script's current scope.
            # Dynamic parameters in functions, for some reason, only exist in $PSBoundParameters instead
            # of being assigned a local variable the way static parameters do.  By calling Set-DynamicParameterVariable,
            # we create these variables for the caller's use in a Parameter Filter or within the mock itself, and
            # by doing it inside this temporary script block, those variables don't stick around longer than they
            # should.
    
            Set-DynamicParameterVariable -SessionState ${Session State} -Parameters $___BoundParameters___ -Metadata ${Meta data}
            # Name property is not present on Application Command metadata in PowerShell 2
            & ${R e p o r t S c o p e} -ModuleName ${M o d u l e N a m e} -CommandName $(try {
                    ${Meta data}.Name
                }
                catch {
                }) -ScriptBlock ${Script Block}
            & ${Script Block} @___BoundParameters___ @___ArgumentList___
        }
    
        Set-ScriptBlockScope -ScriptBlock $scriptBlock -SessionState $mock.SessionState
        $splat = @{
            'Script Block'          = $block.Mock
            '___ArgumentList___'    = $ArgumentList
            '___BoundParameters___' = $BoundParameters
            'Meta data'             = $mock.Metadata
            'Session State'         = $mock.SessionState
            'R e p o r t S c o p e' = { param ($CommandName, $ModuleName, $ScriptBlock)
                Write-ScriptBlockInvocationHint -Hint "Mock - of command $CommandName$(if ($ModuleName) { "from module $ModuleName"})" -ScriptBlock $ScriptBlock }
        }
    
        # the real scriptblock is passed to the other one, we are interested in the mock, not the wrapper, so I pass $block.Mock, and not $scriptBlock
    
        Write-ScriptBlockInvocationHint -Hint "Mock - of command $CommandName$(if ($ModuleName) { "from module $ModuleName"})" -ScriptBlock ($block.Mock)
        & $scriptBlock @splat
    }
    
    function Invoke-InMockScope {
        [CmdletBinding()]
        param (
            [Parameter(Mandatory = $true)]
            [System.Management.Automation.SessionState]
            $SessionState,
    
            [Parameter(Mandatory = $true)]
            [scriptblock]
            $ScriptBlock,
    
            [Parameter(ValueFromRemainingArguments = $true)]
            [object[]]
            $ArgumentList = @()
        )
    
        if ($SessionState.Module) {
            $SessionState.Module.Invoke($ScriptBlock, $ArgumentList)
        }
        else {
            Set-ScriptBlockScope -ScriptBlock $ScriptBlock -SessionState $SessionState
            Write-ScriptBlockInvocationHint -Hint "Mock - InMockScope" -ScriptBlock $ScriptBlock
            & $ScriptBlock @ArgumentList
        }
    }
    
    function Test-ParameterFilter {
        [CmdletBinding()]
        param (
            [Parameter(Mandatory = $true)]
            [scriptblock]
            $ScriptBlock,
    
            [System.Collections.IDictionary]
            $BoundParameters,
    
            [object[]]
            $ArgumentList,
    
            [System.Management.Automation.CommandMetadata]
            $Metadata
        )
    
        if ($null -eq $BoundParameters) {
            $BoundParameters = @{}
        }
        if ($null -eq $ArgumentList) {
            $ArgumentList = @()
        }
    
        $paramBlock = Get-ParamBlockFromBoundParameters -BoundParameters $BoundParameters -Metadata $Metadata
    
        $scriptBlockString = "
            $paramBlock
    
            Set-StrictMode -Off
            $ScriptBlock
        "
        Write-Hint "Unbinding ScriptBlock from '$(Get-ScriptBlockHint $ScriptBlock)'"
        $cmd = [scriptblock]::Create($scriptBlockString)
        Set-ScriptBlockHint -ScriptBlock $cmd -Hint "Unbound ScriptBlock from Test-ParameterFilter"
        Set-ScriptBlockScope -ScriptBlock $cmd -SessionState $pester.SessionState
    
        Write-ScriptBlockInvocationHint -Hint "Mock - Parameter filter" -ScriptBlock $cmd
        & $cmd @BoundParameters @ArgumentList
    }
    
    function Get-ParamBlockFromBoundParameters {
        param (
            [System.Collections.IDictionary] $BoundParameters,
            [System.Management.Automation.CommandMetadata] $Metadata
        )
    
        $params = foreach ($paramName in $BoundParameters.get_Keys()) {
            if (IsCommonParameter -Name $paramName -Metadata $Metadata) {
                continue
            }
    
            "`${$paramName}"
        }
    
        $params = $params -join ','
    
        if ($null -ne $Metadata) {
            $cmdletBinding = [System.Management.Automation.ProxyCommand]::GetCmdletBindingAttribute($Metadata)
        }
        else {
            $cmdletBinding = ''
        }
    
        return "$cmdletBinding param ($params)"
    }
    
    function IsCommonParameter {
        param (
            [string] $Name,
            [System.Management.Automation.CommandMetadata] $Metadata
        )
    
        if ($null -ne $Metadata) {
            if ([System.Management.Automation.Internal.CommonParameters].GetProperty($Name)) {
                return $true
            }
            if ($Metadata.SupportsShouldProcess -and [System.Management.Automation.Internal.ShouldProcessParameters].GetProperty($Name)) {
                return $true
            }
            if ($PSVersionTable.PSVersion.Major -ge 3 -and $Metadata.SupportsPaging -and [System.Management.Automation.PagingParameters].GetProperty($Name)) {
                return $true
            }
            if ($Metadata.SupportsTransactions -and [System.Management.Automation.Internal.TransactionParameters].GetProperty($Name)) {
                return $true
            }
        }
    
        return $false
    }
    
    function Set-DynamicParameterVariable {
        <#
            .SYNOPSIS
            This command is used by Pester's Mocking framework.  You do not need to call it directly.
        #>
    
        param (
            [Parameter(Mandatory = $true)]
            [System.Management.Automation.SessionState]
            $SessionState,
    
            [hashtable]
            $Parameters,
    
            [System.Management.Automation.CommandMetadata]
            $Metadata
        )
    
        if ($null -eq $Parameters) {
            $Parameters = @{}
        }
    
        foreach ($keyValuePair in $Parameters.GetEnumerator()) {
            $variableName = $keyValuePair.Key
    
            if (-not (IsCommonParameter -Name $variableName -Metadata $Metadata)) {
                if ($ExecutionContext.SessionState -eq $SessionState) {
                    & $SafeCommands['Set-Variable'] -Scope 1 -Name $variableName -Value $keyValuePair.Value -Force -Confirm:$false -WhatIf:$false
                }
                else {
                    $SessionState.PSVariable.Set($variableName, $keyValuePair.Value)
                }
            }
        }
    }
    
    function Get-DynamicParamBlock {
        param (
            [scriptblock] $ScriptBlock
        )
    
        if ($PSVersionTable.PSVersion.Major -le 2) {
            $flags = [System.Reflection.BindingFlags]'Instance, NonPublic'
            $dynamicParams = [scriptblock].GetField('_dynamicParams', $flags).GetValue($ScriptBlock)
    
            if ($null -ne $dynamicParams) {
                return $dynamicParams.ToString()
    
            }
        }
        else {
            If ( $ScriptBlock.AST.psobject.Properties.Name -match "Body") {
                if ($null -ne $ScriptBlock.Ast.Body.DynamicParamBlock) {
                    $statements = $ScriptBlock.Ast.Body.DynamicParamBlock.Statements |
                        & $SafeCommands['Select-Object'] -ExpandProperty Extent |
                        & $SafeCommands['Select-Object'] -ExpandProperty Text
    
                    return $statements -join "$([System.Environment]::NewLine)"
                }
            }
        }
    }
    
    function Get-MockDynamicParameter {
        <#
            .SYNOPSIS
            This command is used by Pester's Mocking framework.  You do not need to call it directly.
        #>
    
        [CmdletBinding()]
        param (
            [Parameter(Mandatory = $true, ParameterSetName = 'Cmdlet')]
            [string] $CmdletName,
    
            [Parameter(Mandatory = $true, ParameterSetName = 'Function')]
            [string] $FunctionName,
    
            [Parameter(ParameterSetName = 'Function')]
            [string] $ModuleName,
    
            [System.Collections.IDictionary] $Parameters,
    
            [object] $Cmdlet
        )
    
        switch ($PSCmdlet.ParameterSetName) {
            'Cmdlet' {
                Get-DynamicParametersForCmdlet -CmdletName $CmdletName -Parameters $Parameters
            }
    
            'Function' {
                Get-DynamicParametersForMockedFunction -FunctionName $FunctionName -ModuleName $ModuleName -Parameters $Parameters -Cmdlet $Cmdlet
            }
        }
    }
    
    function Get-DynamicParametersForCmdlet {
        [CmdletBinding()]
        param (
            [Parameter(Mandatory = $true)]
            [string] $CmdletName,
    
            [ValidateScript( {
                    if ($PSVersionTable.PSVersion.Major -ge 3 -and
                        $null -ne $_ -and
                        $_.GetType().FullName -ne 'System.Management.Automation.PSBoundParametersDictionary') {
                        throw 'The -Parameters argument must be a PSBoundParametersDictionary object ($PSBoundParameters).'
                    }
    
                    return $true
                })]
            [System.Collections.IDictionary] $Parameters
        )
    
        try {
            $command = & $SafeCommands['Get-Command'] -Name $CmdletName -CommandType Cmdlet -ErrorAction Stop
    
            if (@($command).Count -gt 1) {
                throw "Name '$CmdletName' resolved to multiple Cmdlets"
            }
        }
        catch {
            $PSCmdlet.ThrowTerminatingError($_)
        }
    
        if ($null -eq $command.ImplementingType.GetInterface('IDynamicParameters', $true)) {
            return
        }
    
        if ('5.0.10586.122' -lt $PSVersionTable.PSVersion) {
            # Older version of PS required Reflection to do this.  It has run into problems on occasion with certain cmdlets,
            # such as ActiveDirectory and AzureRM, so we'll take advantage of the newer PSv5 engine features if at all possible.
    
            if ($null -eq $Parameters) {
                $paramsArg = @()
            }
            else {
                $paramsArg = @($Parameters)
            }
    
            $command = $ExecutionContext.InvokeCommand.GetCommand($CmdletName, [System.Management.Automation.CommandTypes]::Cmdlet, $paramsArg)
            $paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new()
    
            foreach ($param in $command.Parameters.Values) {
                if (-not $param.IsDynamic) {
                    continue
                }
                if ($Parameters.ContainsKey($param.Name)) {
                    continue
                }
    
                $dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes)
                $paramDictionary.Add($param.Name, $dynParam)
            }
    
            return $paramDictionary
        }
        else {
            if ($null -eq $Parameters) {
                $Parameters = @{}
            }
    
            $cmdlet = & $SafeCommands['New-Object'] $command.ImplementingType.FullName
    
            $flags = [System.Reflection.BindingFlags]'Instance, Nonpublic'
            $context = $ExecutionContext.GetType().GetField('_context', $flags).GetValue($ExecutionContext)
            [System.Management.Automation.Cmdlet].GetProperty('Context', $flags).SetValue($cmdlet, $context, $null)
    
            foreach ($keyValuePair in $Parameters.GetEnumerator()) {
                $property = $cmdlet.GetType().GetProperty($keyValuePair.Key)
                if ($null -eq $property -or -not $property.CanWrite) {
                    continue
                }
    
                $isParameter = [bool]($property.GetCustomAttributes([System.Management.Automation.ParameterAttribute], $true))
                if (-not $isParameter) {
                    continue
                }
    
                $property.SetValue($cmdlet, $keyValuePair.Value, $null)
            }
    
            try {
                # This unary comma is important in some cases.  On Windows 7 systems, the ActiveDirectory module cmdlets
                # return objects from this method which implement IEnumerable for some reason, and even cause PowerShell
                # to throw an exception when it tries to cast the object to that interface.
    
                # We avoid that problem by wrapping the result of GetDynamicParameters() in a one-element array with the
                # unary comma.  PowerShell enumerates that array instead of trying to enumerate the goofy object, and
                # everyone's happy.
    
                # Love the comma.  Don't delete it.  We don't have a test for this yet, unless we can get the AD module
                # on a Server 2008 R2 build server, or until we write some C# code to reproduce its goofy behavior.
    
                , $cmdlet.GetDynamicParameters()
            }
            catch [System.NotImplementedException] {
                # Some cmdlets implement IDynamicParameters but then throw a NotImplementedException.  I have no idea why.  Ignore them.
            }
        }
    }
    
    function Get-DynamicParametersForMockedFunction {
        [CmdletBinding()]
        param (
            [Parameter(Mandatory = $true)]
            [string]
            $FunctionName,
    
            [string]
            $ModuleName,
    
            [System.Collections.IDictionary]
            $Parameters,
    
            [object]
            $Cmdlet
        )
    
        $mock = $mockTable["$ModuleName||$FunctionName"]
    
        if (-not $mock) {
            throw "Internal error detected:  Mock for '$FunctionName' in module '$ModuleName' was called, but does not exist in the mock table."
        }
    
        if ($mock.DynamicParamScriptBlock) {
            $splat = @{ 'P S Cmdlet' = $Cmdlet }
            return & $mock.DynamicParamScriptBlock @Parameters @splat
        }
    }
    
    function Test-IsClosure {
        [CmdletBinding()]
        param (
            [Parameter(Mandatory = $true)]
            [scriptblock]
            $ScriptBlock
        )
    
        $sessionStateInternal = Get-ScriptBlockScope -ScriptBlock $ScriptBlock
        if ($null -eq $sessionStateInternal) {
            return $false
        }
    
        $flags = [System.Reflection.BindingFlags]'Instance,NonPublic'
        $module = $sessionStateInternal.GetType().GetProperty('Module', $flags).GetValue($sessionStateInternal, $null)
    
        return (
            $null -ne $module -and
            $module.Name -match '^__DynamicModule_([a-f\d-]+)$' -and
            $null -ne ($matches[1] -as [guid])
        )
    }
    
    function Remove-MockFunctionsAndAliases {
        # when a test is terminated (e.g. by stopping at a breakpoint and then stoping the execution of the script)
        # the aliases and bootstrap functions for the currently mocked functions will remain in place
        # Then on subsequent runs the bootstrap function will be picked up instead of the real command,
        # because there is still an alias associated with it, and the test will fail.
        # So before putting Pester state in place we should make sure that all Pester mocks are gone
        # by deleting every alias pointing to a function that starts with PesterMock_. Then we also delete the
        # bootstrap function.
        foreach ($alias in (& $script:SafeCommands['Get-Alias'] -Definition "PesterMock_*")) {
            & $script:SafeCommands['Remove-Item'] "alias:/$($alias.Name)"
        }
    
        foreach ($bootstrapFunction in (& $script:SafeCommands['Get-Command'] -Name "PesterMock_*")) {
            & $script:SafeCommands['Remove-Item'] "function:/$($bootstrapFunction.Name)"
        }
    }
    
    function Repair-ConflictingParameters {
        [CmdletBinding()]
        [OutputType([System.Management.Automation.CommandMetadata])]
        param(
            [Parameter(Mandatory = $true)]
            [System.Management.Automation.CommandMetadata]
            $Metadata
        )
    
        $paramMetadatas = @()
        $paramMetadatas += $Metadata.Parameters.Values
    
        foreach ($paramMetadata in $paramMetadatas) {
            if ($paramMetadata.IsDynamic) {
                continue
            }
    
            $conflictingParams = Get-ConflictingParameterNames
            if ($conflictingParams -contains $paramMetadata.Name) {
                $paramName = $paramMetadata.Name
                $newName = "_$paramName"
                $paramMetadata.Name = $newName
                $paramMetadata.Aliases.Add($paramName)
    
                $null = $Metadata.Parameters.Remove($paramName)
                $Metadata.Parameters.Add($newName, $paramMetadata)
            }
        }
    
        $Metadata
    }
    
    function Reset-ConflictingParameters {
        [CmdletBinding()]
        [OutputType([hashtable])]
        param(
            [Parameter(Mandatory = $true)]
            [hashtable]
            $BoundParameters
        )
    
        $parameters = $BoundParameters.Clone()
        $names = Get-ConflictingParameterNames
    
        foreach ($param in $names) {
            $fixedName = "_$param"
    
            if (-not $parameters.ContainsKey($fixedName)) {
                continue
            }
    
            $parameters[$param] = $parameters[$fixedName]
            $null = $parameters.Remove($fixedName)
        }
    
        $parameters
    }
    
    $script:ConflictingParameterNames = @(
        "PSEdition"
    )
    
    function Get-ConflictingParameterNames {
        $script:ConflictingParameterNames
    }
    
    
    function New-BlockWithoutParameterAliases {
        [CmdletBinding()]
        [OutputType([scriptblock])]
        param(
            [Parameter(Mandatory = $true)]
            [ValidateNotNull()]
            [System.Management.Automation.CommandMetadata]
            $Metadata,
            [Parameter(Mandatory = $true)]
            [ValidateNotNull()]
            [scriptblock]
            $Block
        )
        try {
            if ($PSVersionTable.PSVersion.Major -ge 3) {
                $params = $Metadata.Parameters.Values
                $ast = $Block.Ast
                $blockText = $ast.Extent.Text
                $variables = $Ast.FindAll( { param($ast) $ast -is [System.Management.Automation.Language.VariableExpressionAst]}, $true)
    
                foreach ($var in $variables) {
                    $varName = $var.VariablePath.UserPath
                    $length = $varName.Length
    
                    foreach ($param in $params) {
                        if ($param.Aliases -contains $varName) {
                            $startIndex = $var.Extent.StartOffset - $block.Ast.Extent.StartOffset + 1
    
                            $blockText = $blockText.Remove($startIndex, $length).Insert($startIndex, $param.Name)
                        }
                    }
                }
    
                # Remove top-level brackets {}
                $blockText = $blockText.Remove($blockText.Length - 1, 1).Remove(0, 1)
    
                $Block = [scriptblock]::Create($blockText)
            }
    
            $Block
        }
        catch {
            $PSCmdlet.ThrowTerminatingError($_)
        }
    }
    
    function Invoke-CommonSetupInMockScope {
        [CmdletBinding()]
        param(
            [Parameter(Mandatory = $true)]
            [ValidateNotNull()]
            [hashtable]
            $Mock,
            [Parameter(Mandatory = $true)]
            [ValidateNotNull()]
            [scriptblock]
            $MockScript,
            [Parameter(Mandatory = $true)]
            [ValidateNotNull()]
            [string]
            $CommandName
        )
        try {
            $scriptBlock = { $ExecutionContext.InvokeProvider.Item.Set("Function:\script:$($args[0])", $args[1], $true, $true) }
            $null = Invoke-InMockScope -SessionState $Mock.SessionState -ScriptBlock $scriptBlock -ArgumentList $Mock.BootstrapFunctionName, $MockScript
    
            $mock.Aliases += $CommandName
    
            $scriptBlock = {
                $setAlias = & (Pester\SafeGetCommand) -Name Set-Alias -CommandType Cmdlet -Module Microsoft.PowerShell.Utility
                & $setAlias -Name $args[0] -Value $args[1] -Scope Script
            }
    
            $null = Invoke-InMockScope -SessionState $Mock.SessionState -ScriptBlock $scriptBlock -ArgumentList $CommandName, $Mock.BootstrapFunctionName
    
            if ($Mock.OriginalCommand.ModuleName) {
                $aliasName = "$($Mock.OriginalCommand.ModuleName)\$($CommandName)"
                $Mock.Aliases += $aliasName
    
                $scriptBlock = {
                    $setAlias = & (Pester\SafeGetCommand) -Name Set-Alias -CommandType Cmdlet -Module Microsoft.PowerShell.Utility
                    & $setAlias -Name $args[0] -Value $args[1] -Scope Script
                }
    
                $null = Invoke-InMockScope -SessionState $Mock.SessionState -ScriptBlock $scriptBlock -ArgumentList $aliasName, $Mock.BootstrapFunctionName
            }
    
            if ($Mock.OriginalCommand.CommandType -eq 'Application') {
                $aliasWithoutExt = $CommandName -replace $Mock.OriginalCommand.Extension
    
                $Mock.Aliases += $aliasWithoutExt
    
                $scriptBlock = {
                    $setAlias = & (Pester\SafeGetCommand) -Name Set-Alias -CommandType Cmdlet -Module Microsoft.PowerShell.Utility
                    & $setAlias -Name $args[0] -Value $args[1] -Scope Script
                }
    
                $null = Invoke-InMockScope -SessionState $Mock.SessionState -ScriptBlock $scriptBlock -ArgumentList $aliasWithoutExt, $Mock.BootstrapFunctionName
            }
        }
        catch {
            $PSCmdlet.ThrowTerminatingError($_)
        }
    }
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUADSnK5SvziFRyVscgCBIcB8S
    # USuggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # xWMtI2wG0c5jz8OSUQMJAnj4vg0wDQYJKoZIhvcNAQEBBQAEggEAUyXlTQxxn5fe
    # zxWaNDZo4cO0498iar5QgDn1Hx7pFfcATtiLAAjfJvdJwXclicT7C1Dsg4FapNcD
    # PK5hHOhQustSBMyn0VjUQpZ4NArbbUhscopioNuTFqQdrGZLXbb/CqkPzkCiPpMZ
    # j0hpxQhTqNTsp4RNiyfPxYyfH4rgmGG04rvBrds3vaOtVDGzLmP0HJcg+FtE4Eh0
    # PcBPGRAhX7iiBoF/1FVJ0LNikNMG5Ui7iIMWHkS17IJ5pKXvggiphyXtct5H8rSy
    # qh9kk2IeCiZ7/VFDSZ3nk10j3Y6wpGb7BYLLDLNWUJPYHFt+woPgTTA9qy9e5QAf
    # dyc0AUNA2aGCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzQxWjAjBgkqhkiG9w0BCQQx
    # FgQU3CCoqJ2tc5yhr5ymPJxLzgaLEMowDQYJKoZIhvcNAQEBBQAEggEAfVu0w39E
    # sTzr7ioWZuAsZBtpGh2U134pmuvllUS6Z2sYWM9ZxeRWWztCq/dckWdXvGiMTpSQ
    # bU+bRLeu2K6FHQ5aQPt0Cp9yYXMQwYDD9l2uCIEnS2KHNugREQEuno9wpKibvFiL
    # abpE3rkDklHZqxJ8DBs8BWTWR8D2MkE8fZmEoI0J6pitRE7sO+TpByaLKatnzKXq
    # ERJuVtZHKcCB2bwfP3pjQaxudQGux/fT0miU7INftIOcGEZjtSHR7e6lYFSYACVO
    # cN1M7woLEbSpgcYvfnj2Uutg6f2bxjHCBETars72DlBIyqHLCyRGGK6K6ELI3cvD
    # LkUq6o0hc0Pxrw==
    # SIG # End signature block
    
  • tools\Functions\New-Fixture.ps1 Show
    function New-Fixture {
        <#
        .SYNOPSIS
        This function generates two scripts, one that defines a function
        and another one that contains its tests.
    
        .DESCRIPTION
        This function generates two scripts, one that defines a function
        and another one that contains its tests. The files are by default
        placed in the current directory and are called and populated as such:
    
    
        The script defining the function: .\Clean.ps1:
    
        function Clean {
    
        }
    
        The script containing the example test .\Clean.Tests.ps1:
    
        $here = Split-Path -Parent $MyInvocation.MyCommand.Path
        $sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.Tests\.', '.'
        . "$here\$sut"
    
        Describe "Clean" {
    
            It "does something useful" {
                $true | Should -Be $false
            }
        }
    
    
        .PARAMETER Name
        Defines the name of the function and the name of the test to be created.
    
        .PARAMETER Path
        Defines path where the test and the function should be created, you can use full or relative path.
        If the parameter is not specified the scripts are created in the current directory.
    
        .EXAMPLE
        New-Fixture -Name Clean
    
        Creates the scripts in the current directory.
    
        .EXAMPLE
        New-Fixture C:\Projects\Cleaner Clean
    
        Creates the scripts in the C:\Projects\Cleaner directory.
    
        .EXAMPLE
        New-Fixture Cleaner Clean
    
        Creates a new folder named Cleaner in the current directory and creates the scripts in it.
    
        .LINK
        Describe
        Context
        It
        about_Pester
        about_Should
        #>
    
        param (
            [String]$Path = $PWD,
            [Parameter(Mandatory = $true)]
            [String]$Name
        )
    
        $Name = $Name -replace '.ps1', ''
    
        #region File contents
        #keep this formatted as is. the format is output to the file as is, including indentation
        $scriptCode = "function $Name {$([System.Environment]::NewLine)$([System.Environment]::NewLine)}"
    
        $testCode = '$here = Split-Path -Parent $MyInvocation.MyCommand.Path
    $sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace ''\.Tests\.'', ''.''
    . "$here\$sut"
    
    Describe "#name#" {
        It "does something useful" {
            $true | Should -Be $false
        }
    }' -replace "#name#", $Name
    
        #endregion
    
        $Path = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($Path)
    
        Create-File -Path $Path -Name "$Name.ps1" -Content $scriptCode
        Create-File -Path $Path -Name "$Name.Tests.ps1" -Content $testCode
    }
    
    function Create-File ($Path, $Name, $Content) {
        if (-not (& $SafeCommands['Test-Path'] -Path $Path)) {
            & $SafeCommands['New-Item'] -ItemType Directory -Path $Path | & $SafeCommands['Out-Null']
        }
    
        $FullPath = & $SafeCommands['Join-Path'] -Path $Path -ChildPath $Name
        if (-not (& $SafeCommands['Test-Path'] -Path $FullPath)) {
            & $SafeCommands['Set-Content'] -Path  $FullPath -Value $Content -Encoding UTF8
            & $SafeCommands['Get-Item'] -Path $FullPath
        }
        else {
            # This is deliberately not sent through $SafeCommands, because our own tests rely on
            # mocking Write-Warning, and it's not really the end of the world if this call happens to
            # be screwed up in an edge case.
            Write-Warning "Skipping the file '$FullPath', because it already exists."
        }
    }
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUdTTN+5zkbPOdEalk2mB5uBCl
    # lH+ggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # ksHH2ydFGqPtpK7sVP0jjYPXLRMwDQYJKoZIhvcNAQEBBQAEggEAlHrFmIoLcnxa
    # TubzfK2QGcPifvlHaFuFGh5sbSnhSiwj+9/PdSbZC0bdRwVP5+v/9cY9O4yooOOR
    # BdYzxyzC6UXYHghRr7S2Bvf/ZUQ9DMIpNpZ7gE1/86SXvEc82Ma8OVkeQJ1uADdy
    # 5ew4P5g7RoktBz8EE/P3Pk15opTDBU3euzdQTU8v3PIkUApLM467ScI0qI2AVywq
    # bh3U4efiZDn6sxBw9+Q5chmlQJqPsBqmD09Gfku1e1XaEleESCfIAuoOCKvyDni/
    # 1hFz68RthEBf9EEZh2QQWqjJhHgAv/4F2btaXchJD1skn4rs7NTjO8VwBnLDBMDv
    # +xIsYSnXbKGCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzQxWjAjBgkqhkiG9w0BCQQx
    # FgQUXxzDWB4dB7sDIqIymKc0rIPImBAwDQYJKoZIhvcNAQEBBQAEggEAJ3iAsEq6
    # U7mADv7CqNLsLnayLfCOK7t4vUyV1NuVivvlCV5DRFwr6C6kQfB4KHTla7Oe0aa8
    # 5R0grcABQqhuGjNvs9WS9do3M+lwdiZlosc0YWfC19XypiUK3Hr9hghX5R0xlp8M
    # vO6sUPXS1FIQXvvAe2A4vBguw1dDwuCF357kWmNm1GLZixHKbyihWib45Svy6hQb
    # IYB3+04AKl20G2sSoF5d4ps1PjT/hQ71+mn58DO+Szj12PiIu8mJefa9S7uS9XqL
    # FmYORgskvUrkNrhNlU4gLNtVrW+h9c3HnGduaNEeoI1YB01KPhu4rAN2RcI58UO3
    # Eti6pNDVaYKz3A==
    # SIG # End signature block
    
  • tools\Functions\New-MockObject.ps1 Show
    function New-MockObject {
        <#
    .SYNOPSIS
    This function instantiates a .NET object from a type.
    
    .DESCRIPTION
    Using the New-MockObject you can mock an object based on .NET type.
    
    An .NET assembly for the particular type must be available in the system and loaded.
    
    .PARAMETER Type
    The .NET type to create an object based on.
    
    .EXAMPLE
    PS> $obj = New-MockObject -Type 'System.Diagnostics.Process'
    PS> $obj.GetType().FullName
        System.Diagnostics.Process
    #>
    
        param (
            [Parameter(Mandatory = $true)]
            [ValidateNotNullOrEmpty()]
            [type]$Type
        )
    
        [System.Runtime.Serialization.Formatterservices]::GetUninitializedObject($Type)
    
    }
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUN2oWx+GL70dUbafNjQZpyRez
    # UdeggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # J7sWrnjKzqImmeHd5l7rNbwd4l4wDQYJKoZIhvcNAQEBBQAEggEAFAF53kLxO20b
    # YZO53rN1YuV8HvqOfW6Tw0A3F+KIcrvez+GQZNz7rjVeKdGqL91PN9rpmbZc68H+
    # nlb7c+ka2u34teuRp+Mcl2HrxbR2Ds8lDS+Vz3iWrNjHuF5oR/ZzIidseruzzi0M
    # ENVNL54QVYSrjTP34pSyqzLwFN3PWBmtgPzMn/o8zJb+5JyIMDDN4bPYyoVx4SIz
    # dHU3z9Ea0Sgjf/lr0XDMSPXhFfCeCPAD9EiPUhhX56J68BrIPofaHHyvzEriaJW6
    # eC10xVSDWcC197v/QnKVg/MClRJEw/iaU5MZtFSg1Z8Gz6G9mxlJBgIQw9Gc7+lA
    # RcFxLPzdl6GCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzQyWjAjBgkqhkiG9w0BCQQx
    # FgQUPJZ/b7OF1b+LyXwMbaIpaP7chDMwDQYJKoZIhvcNAQEBBQAEggEAVG72cz4d
    # y/bvrLj5M4wrxjppRIFSN7y2N2IXD63p0lWOqpMZTuSl458Na4kY6GylIhKFToDP
    # 8ugw/lQMDMa0IN3fl1vXiorNnvmI9GNuAvSXZl4c+bGPBCUaENYCXBnJK62CQXll
    # wEp2yQL2sTvr9W44TVGF5qdUshk7WHZWagvtP0kjmjBpb27R4H30xc3G3lkTrCWQ
    # GZCEwYaq7qJN5r/Nao/xlTp1+YsSXhmtt8UZkXx2eH++alK+nN8aG2A/z017aMfD
    # NuUywFJZFxrjlDGx5c35oxSV6Kl6CXLsxY0yWYUQYp1Ufw3huuAur5G7jtfeGGBI
    # BnWFb2mo3NjCaw==
    # SIG # End signature block
    
  • tools\Functions\Output.ps1 Show
    $Script:ReportStrings = DATA {
        @{
            StartMessage      = "Executing all tests in '{0}'"
            FilterMessage     = ' matching test name {0}'
            TagMessage        = ' with Tags {0}'
            MessageOfs        = "', '"
    
            CoverageTitle     = 'Code coverage report:'
            CoverageMessage   = 'Covered {2:P2} of {3:N0} analyzed {0} in {4:N0} {1}.'
            MissedSingular    = 'Missed command:'
            MissedPlural      = 'Missed commands:'
            CommandSingular   = 'Command'
            CommandPlural     = 'Commands'
            FileSingular      = 'File'
            FilePlural        = 'Files'
    
            Describe          = 'Describing {0}'
            Script            = 'Executing script {0}'
            Context           = 'Context {0}'
            Margin            = '  '
            Timing            = 'Tests completed in {0}'
    
            # If this is set to an empty string, the count won't be printed
            ContextsPassed    = ''
            ContextsFailed    = ''
    
            TestsPassed       = 'Tests Passed: {0}, '
            TestsFailed       = 'Failed: {0}, '
            TestsSkipped      = 'Skipped: {0}, '
            TestsPending      = 'Pending: {0}, '
            TestsInconclusive = 'Inconclusive: {0} '
        }
    }
    
    $Script:ReportTheme = DATA {
        @{
            Describe         = 'Green'
            DescribeDetail   = 'DarkYellow'
            Context          = 'Cyan'
            ContextDetail    = 'DarkCyan'
            Pass             = 'DarkGreen'
            PassTime         = 'DarkGray'
            Fail             = 'Red'
            FailTime         = 'DarkGray'
            Skipped          = 'Yellow'
            SkippedTime      = 'DarkGray'
            Pending          = 'Gray'
            PendingTime      = 'DarkGray'
            Inconclusive     = 'Gray'
            InconclusiveTime = 'DarkGray'
            Incomplete       = 'Yellow'
            IncompleteTime   = 'DarkGray'
            Foreground       = 'White'
            Information      = 'DarkGray'
            Coverage         = 'White'
            CoverageWarn     = 'DarkRed'
        }
    }
    
    function Format-PesterPath ($Path, [String]$Delimiter) {
        # -is check is not enough for the arrays, the incoming value will likely be object[]
        # so we have to check if we can upcast to our required type
    
        if ($null -eq $Path) {
            $null
        }
        elseif ($Path -is [String]) {
            $Path
        }
        elseif ($Path -is [hashtable]) {
            # a well formed pester hashtable contains Path
            $Path.Path
        }
        elseif ($null -ne ($path -as [hashtable[]])) {
            ($path | ForEach-Object { $_.Path }) -join $Delimiter
        }
        # needs to stay at the bottom because almost everything can be upcast to array of string
        elseif ($Path -as [String[]]) {
            $Path -join $Delimiter
        }
    }
    
    function Write-PesterStart {
        param(
            [Parameter(mandatory = $true, valueFromPipeline = $true)]
            $PesterState,
            $Path = '.'
        )
        process {
            if (-not ( $pester.Show | Has-Flag 'All, Fails, Header')) {
                return
            }
    
            $OFS = $ReportStrings.MessageOfs
    
            $message = $ReportStrings.StartMessage -f (Format-PesterPath $Path -Delimiter $OFS)
            if ($PesterState.TestNameFilter) {
                $message += $ReportStrings.FilterMessage -f "$($PesterState.TestNameFilter)"
            }
            if ($PesterState.ScriptBlockFilter) {
                $m = $(foreach ($m in $PesterState.ScriptBlockFilter) { "$($m.Path):$($m.Line)" }) -join ", "
                $message += $ReportStrings.FilterMessage -f $m
            }
            if ($PesterState.TagFilter) {
                $message += $ReportStrings.TagMessage -f "$($PesterState.TagFilter)"
            }
    
            & $SafeCommands['Write-Host'] $message -Foreground $ReportTheme.Foreground
        }
    }
    
    function Write-Describe {
        param (
            [Parameter(mandatory = $true, valueFromPipeline = $true)]
            $Describe,
    
            [string] $CommandUsed = 'Describe'
        )
        process {
            if (-not ( $pester.Show | Has-Flag Describe)) {
                return
            }
    
            $margin = $ReportStrings.Margin * $pester.IndentLevel
    
            $Text = if ($Describe.PSObject.Properties['Name'] -and $Describe.Name) {
                $ReportStrings.$CommandUsed -f $Describe.Name
            }
            else {
                $ReportStrings.$CommandUsed -f $Describe
            }
    
            & $SafeCommands['Write-Host']
            & $SafeCommands['Write-Host'] "${margin}${Text}" -ForegroundColor $ReportTheme.Describe
            # If the feature has a longer description, write that too
            if ($Describe.PSObject.Properties['Description'] -and $Describe.Description) {
                $Describe.Description -split "$([System.Environment]::NewLine)" | ForEach-Object {
                    & $SafeCommands['Write-Host'] ($ReportStrings.Margin * ($pester.IndentLevel + 1)) $_ -ForegroundColor $ReportTheme.DescribeDetail
                }
            }
        }
    }
    
    function Write-Context {
        param (
            [Parameter(mandatory = $true, valueFromPipeline = $true)]
            $Context
        )
        process {
            if (-not ( $pester.Show | Has-Flag Context)) {
                return
            }
            $Text = if ($Context.PSObject.Properties['Name'] -and $Context.Name) {
                $ReportStrings.Context -f $Context.Name
            }
            else {
                $ReportStrings.Context -f $Context
            }
    
            & $SafeCommands['Write-Host']
            & $SafeCommands['Write-Host'] ($ReportStrings.Margin + $Text) -ForegroundColor $ReportTheme.Context
            # If the scenario has a longer description, write that too
            if ($Context.PSObject.Properties['Description'] -and $Context.Description) {
                $Context.Description -split "$([System.Environment]::NewLine)" | ForEach-Object {
                    & $SafeCommands['Write-Host'] (" " * $ReportStrings.Context.Length) $_ -ForegroundColor $ReportTheme.ContextDetail
                }
            }
        }
    }
    
    function ConvertTo-PesterResult {
        param(
            [String] $Name,
            [Nullable[TimeSpan]] $Time,
            [System.Management.Automation.ErrorRecord] $ErrorRecord
        )
    
        $testResult = @{
            Name           = $Name
            Time           = $time
            FailureMessage = ""
            StackTrace     = ""
            ErrorRecord    = $null
            Success        = $false
            Result         = "Failed"
        }
    
        if (-not $ErrorRecord) {
            $testResult.Result = "Passed"
            $testResult.Success = $true
            return $testResult
        }
    
        if (@('PesterAssertionFailed', 'PesterTestSkipped', 'PesterTestInconclusive', 'PesterTestPending') -contains $ErrorRecord.FullyQualifiedErrorID) {
            # we use TargetObject to pass structured information about the error.
            $details = $ErrorRecord.TargetObject
    
            $failureMessage = $details.Message
            $file = $details.File
            $line = $details.Line
            $Text = $details.LineText
    
            if (-not $Pester.Strict) {
                switch ($ErrorRecord.FullyQualifiedErrorID) {
                    PesterTestInconclusive {
                        $testResult.Result = "Inconclusive"; break;
                    }
                    PesterTestPending {
                        $testResult.Result = "Pending"; break;
                    }
                    PesterTestSkipped {
                        $testResult.Result = "Skipped"; break;
                    }
                }
            }
        }
        else {
            $failureMessage = $ErrorRecord.ToString()
            $file = $ErrorRecord.InvocationInfo.ScriptName
            $line = $ErrorRecord.InvocationInfo.ScriptLineNumber
            $Text = $ErrorRecord.InvocationInfo.Line
        }
    
        $testResult.FailureMessage = $failureMessage
        $testResult.StackTrace = "at <ScriptBlock>, ${file}: line ${line}$([System.Environment]::NewLine)${line}: ${Text}"
        $testResult.ErrorRecord = $ErrorRecord
    
        return $testResult
    }
    
    function Remove-Comments ($Text) {
        $text -replace "(?s)(<#.*#>)" -replace "\#.*"
    }
    
    function Write-PesterResult {
        param (
            [Parameter(mandatory = $true, valueFromPipeline = $true)]
            $TestResult
        )
    
        process {
            $quiet = $pester.Show -eq [Pester.OutputTypes]::None
            $OutputType = [Pester.OutputTypes] $TestResult.Result
            $writeToScreen = $pester.Show | Has-Flag $OutputType
            $skipOutput = $quiet -or (-not $writeToScreen)
    
            if ($skipOutput) {
                return
            }
    
            $margin = $ReportStrings.Margin * ($pester.IndentLevel + 1)
            $error_margin = $margin + $ReportStrings.Margin
            $output = $TestResult.Name
            $humanTime = Get-HumanTime $TestResult.Time.TotalSeconds
    
            if (-not ($OutputType | Has-Flag 'Default, Summary')) {
                switch ($TestResult.Result) {
                    Passed {
                        & $SafeCommands['Write-Host'] -ForegroundColor $ReportTheme.Pass "$margin[+] $output" -NoNewLine
                        & $SafeCommands['Write-Host'] -ForegroundColor $ReportTheme.PassTime " $humanTime"
                        break
                    }
    
                    Failed {
                        & $SafeCommands['Write-Host'] -ForegroundColor $ReportTheme.Fail "$margin[-] $output" -NoNewLine
                        & $SafeCommands['Write-Host'] -ForegroundColor $ReportTheme.FailTime " $humanTime"
    
                        if ($pester.IncludeVSCodeMarker) {
                            & $SafeCommands['Write-Host'] -ForegroundColor $ReportTheme.Fail $($TestResult.StackTrace -replace '(?m)^', $error_margin)
                            & $SafeCommands['Write-Host'] -ForegroundColor $ReportTheme.Fail $($TestResult.FailureMessage -replace '(?m)^', $error_margin)
                        }
                        else {
                            $TestResult.ErrorRecord |
                                ConvertTo-FailureLines |
                                ForEach-Object {$_.Message + $_.Trace} |
                                ForEach-Object { & $SafeCommands['Write-Host'] -ForegroundColor $ReportTheme.Fail $($_ -replace '(?m)^', $error_margin) }
                        }
                        break
                    }
    
                    Skipped {
                        $targetObject = if ($null -ne $testresult.ErrorRecord -and
                            ($o = $testresult.ErrorRecord.PSObject.Properties.Item("TargetObject"))) { $o.Value }
                        $because = if ($targetObject -and $targetObject.Data.Because) {
                            ", because $($testresult.ErrorRecord.TargetObject.Data.Because)"
                        }
                        else {
                            $null
                        }
                        & $SafeCommands['Write-Host'] -ForegroundColor $ReportTheme.Skipped "$margin[!] $output" -NoNewLine
                        & $SafeCommands['Write-Host'] -ForegroundColor $ReportTheme.Skipped ", is skipped$because" -NoNewLine
                        & $SafeCommands['Write-Host'] -ForegroundColor $ReportTheme.SkippedTime " $humanTime"
                        break
                    }
    
                    Pending {
                        $because = if ($testresult.ErrorRecord.TargetObject.Data.Because) {
                            ", because $($testresult.ErrorRecord.TargetObject.Data.Because)"
                        }
                        else {
                            $null
                        }
                        & $SafeCommands['Write-Host'] -ForegroundColor $ReportTheme.Pending "$margin[?] $output" -NoNewLine
                        & $SafeCommands['Write-Host'] -ForegroundColor $ReportTheme.Pending ", is pending$because" -NoNewLine
                        & $SafeCommands['Write-Host'] -ForegroundColor $ReportTheme.PendingTime " $humanTime"
                        break
                    }
    
                    Inconclusive {
                        $because = if ($testresult.ErrorRecord.TargetObject.Data.Because) {
                            ", because $($testresult.ErrorRecord.TargetObject.Data.Because)"
                        }
                        else {
                            $null
                        }
                        & $SafeCommands['Write-Host'] -ForegroundColor $ReportTheme.Inconclusive "$margin[?] $output" -NoNewLine
                        & $SafeCommands['Write-Host'] -ForegroundColor $ReportTheme.Inconclusive ", is inconclusive$because" -NoNewLine
                        & $SafeCommands['Write-Host'] -ForegroundColor $ReportTheme.InconclusiveTime " $humanTime"
    
                        break
                    }
    
                    default {
                        # TODO:  Add actual Incomplete status as default rather than checking for null time.
                        if ($null -eq $TestResult.Time) {
                            & $SafeCommands['Write-Host'] -ForegroundColor $ReportTheme.Incomplete "$margin[?] $output" -NoNewLine
                            & $SafeCommands['Write-Host'] -ForegroundColor $ReportTheme.IncompleteTime " $humanTime"
                        }
                    }
                }
            }
        }
    }
    
    function Write-PesterReport {
        param (
            [Parameter(mandatory = $true, valueFromPipeline = $true)]
            $PesterState
        )
        if (-not ($PesterState.Show | Has-Flag Summary)) {
            return
        }
    
        & $SafeCommands['Write-Host'] ($ReportStrings.Timing -f (Get-HumanTime $PesterState.Time.TotalSeconds)) -Foreground $ReportTheme.Foreground
    
        $Success, $Failure = if ($PesterState.FailedCount -gt 0) {
            $ReportTheme.Foreground, $ReportTheme.Fail
        }
        else {
            $ReportTheme.Pass, $ReportTheme.Information
        }
        $Skipped = if ($PesterState.SkippedCount -gt 0) {
            $ReportTheme.Skipped
        }
        else {
            $ReportTheme.Information
        }
        $Pending = if ($PesterState.PendingCount -gt 0) {
            $ReportTheme.Pending
        }
        else {
            $ReportTheme.Information
        }
        $Inconclusive = if ($PesterState.InconclusiveCount -gt 0) {
            $ReportTheme.Inconclusive
        }
        else {
            $ReportTheme.Information
        }
    
        Try {
            $PesterStatePassedScenariosCount = $PesterState.PassedScenarios.Count
        }
        Catch {
            $PesterStatePassedScenariosCount = 0
        }
    
        Try {
            $PesterStateFailedScenariosCount = $PesterState.FailedScenarios.Count
        }
        Catch {
            $PesterStateFailedScenariosCount = 0
        }
    
        if ($ReportStrings.ContextsPassed) {
            & $SafeCommands['Write-Host'] ($ReportStrings.ContextsPassed -f $PesterStatePassedScenariosCount) -Foreground $Success -NoNewLine
            & $SafeCommands['Write-Host'] ($ReportStrings.ContextsFailed -f $PesterStateFailedScenariosCount) -Foreground $Failure
        }
        if ($ReportStrings.TestsPassed) {
            & $SafeCommands['Write-Host'] ($ReportStrings.TestsPassed -f $PesterState.PassedCount) -Foreground $Success -NoNewLine
            & $SafeCommands['Write-Host'] ($ReportStrings.TestsFailed -f $PesterState.FailedCount) -Foreground $Failure -NoNewLine
            & $SafeCommands['Write-Host'] ($ReportStrings.TestsSkipped -f $PesterState.SkippedCount) -Foreground $Skipped -NoNewLine
            & $SafeCommands['Write-Host'] ($ReportStrings.TestsPending -f $PesterState.PendingCount) -Foreground $Pending -NoNewLine
            & $SafeCommands['Write-Host'] ($ReportStrings.TestsInconclusive -f $PesterState.InconclusiveCount) -Foreground $Inconclusive
        }
    }
    
    function Write-CoverageReport {
        param ([object] $CoverageReport)
    
        if ($null -eq $CoverageReport -or ($pester.Show -eq [Pester.OutputTypes]::None) -or $CoverageReport.NumberOfCommandsAnalyzed -eq 0) {
            return
        }
    
        $totalCommandCount = $CoverageReport.NumberOfCommandsAnalyzed
        $fileCount = $CoverageReport.NumberOfFilesAnalyzed
        $executedPercent = ($CoverageReport.NumberOfCommandsExecuted / $CoverageReport.NumberOfCommandsAnalyzed).ToString("P2")
    
        $command = if ($totalCommandCount -gt 1) {
            $ReportStrings.CommandPlural
        }
        else {
            $ReportStrings.CommandSingular
        }
        $file = if ($fileCount -gt 1) {
            $ReportStrings.FilePlural
        }
        else {
            $ReportStrings.FileSingular
        }
    
        $commonParent = Get-CommonParentPath -Path $CoverageReport.AnalyzedFiles
        $report = $CoverageReport.MissedCommands | & $SafeCommands['Select-Object'] -Property @(
            @{ Name = 'File'; Expression = { Get-RelativePath -Path $_.File -RelativeTo $commonParent } }
            'Class'
            'Function'
            'Line'
            'Command'
        )
    
        & $SafeCommands['Write-Host']
        & $SafeCommands['Write-Host'] $ReportStrings.CoverageTitle -Foreground $ReportTheme.Coverage
    
        if ($CoverageReport.MissedCommands.Count -gt 0) {
            & $SafeCommands['Write-Host'] ($ReportStrings.CoverageMessage -f $command, $file, $executedPercent, $totalCommandCount, $fileCount) -Foreground $ReportTheme.CoverageWarn
            if ($CoverageReport.MissedCommands.Count -eq 1) {
                & $SafeCommands['Write-Host'] $ReportStrings.MissedSingular -Foreground $ReportTheme.CoverageWarn
            }
            else {
                & $SafeCommands['Write-Host'] $ReportStrings.MissedPlural -Foreground $ReportTheme.CoverageWarn
            }
            $report | & $SafeCommands['Format-Table'] -AutoSize | & $SafeCommands['Out-Host']
        }
        else {
            & $SafeCommands['Write-Host'] ($ReportStrings.CoverageMessage -f $command, $file, $executedPercent, $totalCommandCount, $fileCount) -Foreground $ReportTheme.Coverage
        }
    }
    
    function ConvertTo-FailureLines {
        param (
            [Parameter(mandatory = $true, valueFromPipeline = $true)]
            $ErrorRecord
        )
        process {
            $lines = & $script:SafeCommands['New-Object'] psobject -Property @{
                Message = @()
                Trace   = @()
            }
    
            ## convert the exception messages
            $exception = $ErrorRecord.Exception
            $exceptionLines = @()
    
            while ($exception) {
                $exceptionName = $exception.GetType().Name
                $thisLines = $exception.Message.Split([string[]]($([System.Environment]::NewLine), "\n", "`n"), [System.StringSplitOptions]::RemoveEmptyEntries)
                if ($ErrorRecord.FullyQualifiedErrorId -ne 'PesterAssertionFailed') {
                    $thisLines[0] = "$exceptionName`: $($thisLines[0])"
                }
                [array]::Reverse($thisLines)
                $exceptionLines += $thisLines
                $exception = $exception.InnerException
            }
            [array]::Reverse($exceptionLines)
            $lines.Message += $exceptionLines
            if ($ErrorRecord.FullyQualifiedErrorId -eq 'PesterAssertionFailed') {
                $lines.Message += "$($ErrorRecord.TargetObject.Line)`: $($ErrorRecord.TargetObject.LineText)".Split([string[]]($([System.Environment]::NewLine), "\n", "`n"), [System.StringSplitOptions]::RemoveEmptyEntries)
            }
    
            if ( -not ($ErrorRecord | & $SafeCommands['Get-Member'] -Name ScriptStackTrace) ) {
                if ($ErrorRecord.FullyQualifiedErrorID -eq 'PesterAssertionFailed') {
                    $lines.Trace += "at line: $($ErrorRecord.TargetObject.Line) in $($ErrorRecord.TargetObject.File)"
                }
                else {
                    $lines.Trace += "at line: $($ErrorRecord.InvocationInfo.ScriptLineNumber) in $($ErrorRecord.InvocationInfo.ScriptName)"
                }
                return $lines
            }
    
            ## convert the stack trace if present (there might be none if we are raising the error ourselves)
            # todo: this is a workaround see https://github.com/pester/Pester/pull/886
            if ($null -ne $ErrorRecord.ScriptStackTrace) {
                $traceLines = $ErrorRecord.ScriptStackTrace.Split([Environment]::NewLine, [System.StringSplitOptions]::RemoveEmptyEntries)
            }
    
            $count = 0
    
            # omit the lines internal to Pester
    
            If ((GetPesterOS) -ne 'Windows') {
    
                [String]$pattern1 = '^at (Invoke-Test|Context|Describe|InModuleScope|Invoke-Pester), .*/Functions/.*.ps1: line [0-9]*$'
                [String]$pattern2 = '^at Should<End>, .*/Functions/Assertions/Should.ps1: line [0-9]*$'
                [String]$pattern3 = '^at Assert-MockCalled, .*/Functions/Mock.ps1: line [0-9]*$'
                [String]$pattern4 = '^at Invoke-Assertion, .*/Functions/.*.ps1: line [0-9]*$'
                [String]$pattern5 = '^at (<ScriptBlock>|Invoke-Gherkin.*), (<No file>|.*/Functions/.*.ps1): line [0-9]*$'
            }
            Else {
    
                [String]$pattern1 = '^at (Invoke-Test|Context|Describe|InModuleScope|Invoke-Pester), .*\\Functions\\.*.ps1: line [0-9]*$'
                [String]$pattern2 = '^at Should<End>, .*\\Functions\\Assertions\\Should.ps1: line [0-9]*$'
                [String]$pattern3 = '^at Assert-MockCalled, .*\\Functions\\Mock.ps1: line [0-9]*$'
                [String]$pattern4 = '^at Invoke-Assertion, .*\\Functions\\.*.ps1: line [0-9]*$'
                [String]$pattern5 = '^at (<ScriptBlock>|Invoke-Gherkin.*), (<No file>|.*\\Functions\\.*.ps1): line [0-9]*$'
            }
    
            foreach ( $line in $traceLines ) {
                if ( $line -match $pattern1 ) {
                    break
                }
                $count ++
            }
    
            if ($ExecutionContext.SessionState.PSVariable.GetValue("PesterDebugPreference_ShowFullErrors")) {
                $lines.Trace += $traceLines
            }
            else {
                $lines.Trace += $traceLines |
                    & $SafeCommands['Select-Object'] -First $count |
                    & $SafeCommands['Where-Object'] {
                    $_ -notmatch $pattern2 -and
                    $_ -notmatch $pattern3 -and
                    $_ -notmatch $pattern4 -and
                    $_ -notmatch $pattern5
                }
            }
    
            return $lines
        }
    }
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUAzvLGHxMhD7U0HwEA6j+XKhG
    # NMaggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # 8KHnNrKOneJInx/L8Hqn75298tQwDQYJKoZIhvcNAQEBBQAEggEATa6QTX2nRLPX
    # 3oVJeICer8SjwEpCh60ztr5c8m2iY043pVWcYItrNpqXk6M4QS1INRx0SkG1T/lZ
    # Vs4p/H90OMin2VcziLduPEZB7U4r40HEWf0yiCpApIWT7og0rLyPgWkA4oPyD92D
    # Kwf8emY3duEz9ZG7SQrLaB9rTRzTQyEX/xWx2VULEfr1SrMoKSjBNI5bJEZ6Ggut
    # e20yAGUV+T8YjnmLLlcM4rrDiauy8m0a7dRE3OD3Oa8RYJNqveM71Q4w67mttj/z
    # A9N0n6qUwim55lTa/GEi6xrKX40zwCcIqIRL6pAkbLdy5F0TtYTspXPYXub58ueK
    # v7xim9meYKGCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzQzWjAjBgkqhkiG9w0BCQQx
    # FgQUjHg5jI4nB7aOp3MAOcEuo/03VpowDQYJKoZIhvcNAQEBBQAEggEAhTuLqhif
    # 42nGO196zhXS/XtCry7zFAB2VzYOhHbzlLI2+TbSi2TWKMTrpWR3iWdQep5Ps7qR
    # sULLBqasziI8yR6SUtXfTHClFQK8ZS8oeBogsea8erNIcbGOfhp2tnrlHYplY6Q8
    # dbYHPgdMpJD3Vt9iIxdwOcX4pOntFl0jcJDgAk5C67Ude2xAimAqbZCK8tTaOS//
    # hDSGOd5CQVpLY1s/pAt9dXF29kUJNRaNH8B4InSnIjo6JJtEH35KEgccOroI9TwL
    # fsL7Rk7rDuhanhAPVI1u5Vjffuo45s3pAufTdrxWiDoWovJtEEc7kdK9Q4oxFDjx
    # GgYvHaCyOyFWXg==
    # SIG # End signature block
    
  • tools\Functions\PesterState.ps1 Show
    function New-PesterState {
        param (
            [String[]]$TagFilter,
            [String[]]$ExcludeTagFilter,
            [String[]]$TestNameFilter,
            [System.Management.Automation.SessionState]$SessionState,
            [Switch]$Strict,
            [Pester.OutputTypes]$Show = 'All',
            [object]$PesterOption,
            [Switch]$RunningViaInvokePester,
            [Hashtable[]] $ScriptBlockFilter
        )
    
        if ($null -eq $SessionState) {
            $SessionState = Set-SessionStateHint -PassThru  -Hint "Module - Pester (captured in New-PesterState)" -SessionState $ExecutionContext.SessionState
        }
    
        if ($null -eq $PesterOption) {
            $PesterOption = New-PesterOption
        }
        elseif ($PesterOption -is [System.Collections.IDictionary]) {
            try {
                $PesterOption = New-PesterOption @PesterOption
            }
            catch {
                throw
            }
        }
    
        & $SafeCommands['New-Module'] -Name PesterState -AsCustomObject -ArgumentList $TagFilter, $ExcludeTagFilter, $TestNameFilter, $SessionState, $Strict, $Show, $PesterOption, $RunningViaInvokePester -ScriptBlock {
            param (
                [String[]]$_tagFilter,
                [String[]]$_excludeTagFilter,
                [String[]]$_testNameFilter,
                [System.Management.Automation.SessionState]$_sessionState,
                [Switch]$Strict,
                [Pester.OutputTypes]$Show,
                [object]$PesterOption,
                [Switch]$RunningViaInvokePester
            )
    
            #public read-only
            $TagFilter = $_tagFilter
            $ExcludeTagFilter = $_excludeTagFilter
            $TestNameFilter = $_testNameFilter
    
    
            $script:SessionState = $_sessionState
            $script:Stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
            $script:TestStartTime = $null
            $script:TestStopTime = $null
            $script:CommandCoverage = @()
            $script:Strict = $Strict
            $script:Show = $Show
            $script:InTest = $false
    
            $script:TestResult = @()
    
            $script:TotalCount = 0
            $script:Time = [timespan]0
            $script:PassedCount = 0
            $script:FailedCount = 0
            $script:SkippedCount = 0
            $script:PendingCount = 0
            $script:InconclusiveCount = 0
    
            $script:IncludeVSCodeMarker = $PesterOption.IncludeVSCodeMarker
            $script:TestSuiteName = $PesterOption.TestSuiteName
            $script:ScriptBlockFilter = $PesterOption.ScriptBlockFilter
            $script:RunningViaInvokePester = $RunningViaInvokePester
    
            $script:SafeCommands = @{}
    
            $script:SafeCommands['New-Object'] = & (Pester\SafeGetCommand) -Name New-Object          -Module Microsoft.PowerShell.Utility -CommandType Cmdlet
            $script:SafeCommands['Select-Object'] = & (Pester\SafeGetCommand) -Name Select-Object       -Module Microsoft.PowerShell.Utility -CommandType Cmdlet
            $script:SafeCommands['Export-ModuleMember'] = & (Pester\SafeGetCommand) -Name Export-ModuleMember -Module Microsoft.PowerShell.Core    -CommandType Cmdlet
            $script:SafeCommands['Add-Member'] = & (Pester\SafeGetCommand) -Name Add-Member          -Module Microsoft.PowerShell.Utility -CommandType Cmdlet
    
            function New-TestGroup([string] $Name, [string] $Hint) {
                & $SafeCommands['New-Object'] psobject -Property @{
                    Name              = $Name
                    Type              = 'TestGroup'
                    Hint              = $Hint
                    Actions           = [System.Collections.ArrayList]@()
                    BeforeEach        = & $SafeCommands['New-Object'] System.Collections.Generic.List[scriptblock]
                    AfterEach         = & $SafeCommands['New-Object'] System.Collections.Generic.List[scriptblock]
                    BeforeAll         = & $SafeCommands['New-Object'] System.Collections.Generic.List[scriptblock]
                    AfterAll          = & $SafeCommands['New-Object'] System.Collections.Generic.List[scriptblock]
                    TotalCount        = 0
                    StartTime         = $Null
                    Time              = [timespan]0
                    PassedCount       = 0
                    FailedCount       = 0
                    SkippedCount      = 0
                    PendingCount      = 0
                    InconclusiveCount = 0
                }
            }
    
            $script:TestActions = New-TestGroup -Name Pester -Hint Root
            $script:TestGroupStack = & $SafeCommands['New-Object'] System.Collections.Stack
            $script:TestGroupStack.Push($script:TestActions)
    
            function EnterTestGroup([string] $Name, [string] $Hint) {
                $newGroup = New-TestGroup @PSBoundParameters
                $newGroup.StartTime = $script:Stopwatch.Elapsed
                $null = $script:TestGroupStack.Peek().Actions.Add($newGroup)
    
                $script:TestGroupStack.Push($newGroup)
            }
    
            function LeaveTestGroup([string] $Name, [string] $Hint) {
                $StopTime = $script:Stopwatch.Elapsed
                $currentGroup = $script:TestGroupStack.Pop()
    
                if ( $Hint -eq 'Script' ) {
                    $script:Time += $StopTime - $currentGroup.StartTime
                }
    
                $currentGroup.Time = $StopTime - $currentGroup.StartTime
    
                # Removing start time property from output to prevent clutter
                $currentGroup.PSObject.properties.remove('StartTime')
    
                if ($currentGroup.Name -ne $Name -or $currentGroup.Hint -ne $Hint) {
                    throw "TestGroups stack corrupted:  Expected name/hint of '$Name','$Hint'.  Found '$($currentGroup.Name)', '$($currentGroup.Hint)'."
                }
            }
    
            function AddTestResult {
                param (
                    [string]$Name,
                    [ValidateSet("Failed", "Passed", "Skipped", "Pending", "Inconclusive")]
                    [string]$Result,
                    [Nullable[TimeSpan]]$Time,
                    [string]$FailureMessage,
                    [string]$StackTrace,
                    [string] $ParameterizedSuiteName,
                    [System.Collections.IDictionary] $Parameters,
                    [System.Management.Automation.ErrorRecord] $ErrorRecord
                )
    
                # defining this function in here, because otherwise it is not available
                function New-ErrorRecord ([string] $Message, [string] $ErrorId, [string] $File, [string] $Line, [string] $LineText) {
                    $exception = & $SafeCommands['New-Object'] Exception $Message
                    $errorCategory = [Management.Automation.ErrorCategory]::InvalidResult
                    # we use ErrorRecord.TargetObject to pass structured information about the error to a reporting system.
                    $targetObject = @{Message = $Message; File = $File; Line = $Line; LineText = $LineText}
                    $errorRecord = & $SafeCommands['New-Object'] Management.Automation.ErrorRecord $exception, $ErrorID, $errorCategory, $targetObject
                    return $errorRecord
                }
    
                if ($null -eq $Time) {
                    if ( $script:TestStartTime -and $script:TestStopTime ) {
                        $Time = $script:TestStopTime - $script:TestStartTime
                        $script:TestStartTime = $null
                        $script:TestStopTime = [timespan]0
                    }
                    else {
                        $Time = [timespan]0
                    }
                }
    
                if (-not $script:Strict) {
                    $Passed = "Passed", "Skipped", "Pending" -contains $Result
                }
                else {
                    $Passed = $Result -eq "Passed"
                    if (@("Skipped", "Pending", "Inconclusive") -contains $Result) {
                        $FailureMessage = "The test failed because the test was executed in Strict mode and the result '$result' was translated to Failed."
                        $ErrorRecord = New-ErrorRecord -ErrorId "PesterTest$Result" -Message $FailureMessage
                        $Result = "Failed"
                    }
    
                }
    
                $script:TotalCount++
    
                switch ($Result) {
                    Passed {
                        $script:PassedCount++; break;
                    }
                    Failed {
                        $script:FailedCount++; break;
                    }
                    Skipped {
                        $script:SkippedCount++; break;
                    }
                    Pending {
                        $script:PendingCount++; break;
                    }
                    Inconclusive {
                        $script:InconclusiveCount++; break;
                    }
                }
    
                $resultRecord = & $SafeCommands['New-Object'] -TypeName PsObject -Property @{
                    Name                   = $Name
                    Type                   = 'TestCase'
                    Passed                 = $Passed
                    Result                 = $Result
                    Time                   = $Time
                    FailureMessage         = $FailureMessage
                    StackTrace             = $StackTrace
                    ErrorRecord            = $ErrorRecord
                    ParameterizedSuiteName = $ParameterizedSuiteName
                    Parameters             = $Parameters
                    Show                   = $script:Show
                }
    
                $null = $script:TestGroupStack.Peek().Actions.Add($resultRecord)
    
                # Attempting some degree of backward compatibility for the TestResult collection for now; deprecated and will be removed in the future
                $describe = ''
                $contexts = [System.Collections.ArrayList]@()
    
                # make a copy of the stack and reverse it
                $reversedStack = $script:TestGroupStack.ToArray()
                [array]::Reverse($reversedStack)
    
                foreach ($group in $reversedStack) {
                    if ($group.Hint -eq 'Root' -or $group.Hint -eq 'Script') {
                        continue
                    }
                    if ($describe -eq '') {
                        $describe = $group.Name
                    }
                    else {
                        $null = $contexts.Add($group.Name)
                    }
                }
    
                $context = $contexts -join '\'
    
                $script:TestResult += & $SafeCommands['New-Object'] psobject -Property @{
                    Describe               = $describe
                    Context                = $context
                    Name                   = $Name
                    Passed                 = $Passed
                    Result                 = $Result
                    Time                   = $Time
                    FailureMessage         = $FailureMessage
                    StackTrace             = $StackTrace
                    ErrorRecord            = $ErrorRecord
                    ParameterizedSuiteName = $ParameterizedSuiteName
                    Parameters             = $Parameters
                    Show                   = $script:Show
                }
            }
    
            function AddSetupOrTeardownBlock([scriptblock] $ScriptBlock, [string] $CommandName) {
                $currentGroup = $script:TestGroupStack.Peek()
    
                $isSetupCommand = IsSetupCommand -CommandName $CommandName
                $isGroupCommand = IsTestGroupCommand -CommandName $CommandName
    
                if ($isSetupCommand) {
                    if ($isGroupCommand) {
                        $currentGroup.BeforeAll.Add($ScriptBlock)
                    }
                    else {
                        $currentGroup.BeforeEach.Add($ScriptBlock)
                    }
                }
                else {
                    if ($isGroupCommand) {
                        $currentGroup.AfterAll.Add($ScriptBlock)
                    }
                    else {
                        $currentGroup.AfterEach.Add($ScriptBlock)
                    }
                }
            }
    
            function IsSetupCommand {
                param ([string] $CommandName)
                return $CommandName -eq 'BeforeEach' -or $CommandName -eq 'BeforeAll'
            }
    
            function IsTestGroupCommand {
                param ([string] $CommandName)
                return $CommandName -eq 'BeforeAll' -or $CommandName -eq 'AfterAll'
            }
    
            function GetTestCaseSetupBlocks {
                $blocks = @(
                    foreach ($group in $this.TestGroups) {
                        $group.BeforeEach
                    }
                )
    
                return $blocks
            }
    
            function GetTestCaseTeardownBlocks {
                $groups = @($this.TestGroups)
                [Array]::Reverse($groups)
    
                $blocks = @(
                    foreach ($group in $groups) {
                        $group.AfterEach
                    }
                )
    
                return $blocks
            }
    
            function GetCurrentTestGroupSetupBlocks {
                return $script:TestGroupStack.Peek().BeforeAll
            }
    
            function GetCurrentTestGroupTeardownBlocks {
                return $script:TestGroupStack.Peek().AfterAll
            }
    
            function EnterTest {
                if ($script:InTest) {
                    throw 'You are already in a test case.'
                }
    
                $script:TestStartTime = $script:Stopwatch.Elapsed
                $script:InTest = $true
            }
    
            function LeaveTest {
                $script:TestStopTime = $script:Stopwatch.Elapsed
                $script:InTest = $false
            }
    
            $ExportedVariables = "TagFilter",
            "ExcludeTagFilter",
            "TestNameFilter",
            "ScriptBlockFilter",
            "TestResult",
            "SessionState",
            "CommandCoverage",
            "Strict",
            "Show",
            "Time",
            "TotalCount",
            "PassedCount",
            "FailedCount",
            "SkippedCount",
            "PendingCount",
            "InconclusiveCount",
            "IncludeVSCodeMarker",
            "TestActions",
            "TestGroupStack",
            "TestSuiteName",
            "InTest",
            "RunningViaInvokePester"
    
            $ExportedFunctions = "EnterTestGroup",
            "LeaveTestGroup",
            "AddTestResult",
            "AddSetupOrTeardownBlock",
            "GetTestCaseSetupBlocks",
            "GetTestCaseTeardownBlocks",
            "GetCurrentTestGroupSetupBlocks",
            "GetCurrentTestGroupTeardownBlocks",
            "EnterTest",
            "LeaveTest"
    
            & $SafeCommands['Export-ModuleMember'] -Variable $ExportedVariables -function $ExportedFunctions
        }  |
            & $SafeCommands['Add-Member'] -PassThru -MemberType ScriptProperty -Name CurrentTestGroup -Value {
            $this.TestGroupStack.Peek()
        } |
            & $SafeCommands['Add-Member'] -PassThru -MemberType ScriptProperty -Name TestGroups -Value {
            $array = $this.TestGroupStack.ToArray()
            [Array]::Reverse($array)
            return $array
        } |
            & $SafeCommands['Add-Member'] -PassThru -MemberType ScriptProperty -Name IndentLevel -Value {
            # We ignore the root node of the stack here, and don't start indenting until after the Script nodes inside the root
            return [Math]::Max(0, $this.TestGroupStack.Count - 2)
        }
    }
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUmkuNYKsGqbcH53Y8Sif1Q1xt
    # VJuggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # TQqoPXwAe4wH8/3kHDHO/8NT+xwwDQYJKoZIhvcNAQEBBQAEggEAHK2koh1337Hb
    # 1lO4moxDiZJtMeWDkN8xRH5WldSnAYffnvmDdSCzMUtIJjeNl7i+UHhJ8IQr9QKu
    # eeqgJIjVnu3OcDcMVPc2LWCQpCUu3yS4O0SUpXL9B0vsxcJRRkTVkZhZwZj3B3Q8
    # TMzRv4dnvqDlSERV3MHjfU+/33gvtLibjisoljAP3eUcYhCoKD+ce5ZkXm7a2m3F
    # Odo+FMbraf3Pfddko1njxuoLEhWDyPj5qQmiO0apIBHNYgmLRdUa2k2rtdgND8Gd
    # ibIzi67YDm8Gby61CHNtPKX74vBqt0ECG65XJY6nU9XUi467qqyrks9StLRb2Dqt
    # XfP19NGcwKGCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzQzWjAjBgkqhkiG9w0BCQQx
    # FgQUHYxCRxq/2AiLntD4B5C6/ZmIQrIwDQYJKoZIhvcNAQEBBQAEggEAVnR5xRXj
    # iYF+E4NQa1DVmgohI5o648hJUc3V3XdHarer/+dORC1K3q7GCg9Tut1f6tbnWVDl
    # TXXDsQPCRwdvmEA8+eZ8Nlyz5KmCkuDTY1hh/VY+OfM2un2CnKyDUeLNpaxWMsqB
    # wsaYMHn/9pSl6qtM9fgCrb3InHJSEEYsTizuBk9XNNCZWafJQCh9R7P7WpnOWgu3
    # SvtO2qihjVmLugouLmqXGLE2wLQBGIRbjsEDYm6PcS9nigS4XvDtBq6c0WyYr7jf
    # 0dYsxOkPLM4nMGQwlvQrcx/kvzIsTxhv/OWWdoKISDNOxpCold60jzVxHIZTQwcu
    # VxTD+fDd1QyZgg==
    # SIG # End signature block
    
  • tools\Functions\Set-ItResult.ps1 Show
    function Set-ItResult {
        <#
        .SYNOPSIS
        Set-ItResult is used inside the It block to explicitly set the test result
    
        .DESCRIPTION
        Sometimes a test shouldn't be executed, sometimes the condition cannot be evaluated.
        By default such tests would typically fail and produce a big red message.
        Using Set-ItResult it is possible to set the result from the inside of the It script
        block to either inconclusive, pending or skipped.
    
        .PARAMETER Inconclusive
        Sets the test result to inconclusive. Cannot be used at the same time as -Pending or -Skipped
    
        .PARAMETER Pending
        Sets the test result to pending. Cannot be used at the same time as -Inconclusive or -Skipped
    
        .PARAMETER Skipped
        Sets the test result to skipped. Cannot be used at the same time as -Inconclusive or -Pending
    
        .PARAMETER Because
        Similarily to failing tests, skipped and inconclusive tests should have reason. It allows
        to provide information to the user why the test is neither successful nor failed.
    
        .EXAMPLE
        Describe "Example" {
            It "Inconclusive result test" {
                Set-ItResult -Inconclusive -Because "we want it to be inconclusive"
            }
        }
    
        the output should be
    
        [?] Inconclusive result test, is inconclusive, because we want it to be inconclusive
        Tests completed in 0ms
        Tests Passed: 0, Failed: 0, Skipped: 0, Pending: 0, Inconclusive 1
    
    
        .EXAMPLE
        Describe "Example" {
            It "Skipped test" {
                Set-ItResult -Skipped -Because "we want it to be skipped"
            }
        }
    
        the output should be
    
        [!] Skipped test, is skipped, because we want it to be skipped
        Tests completed in 0ms
        Tests Passed: 0, Failed: 0, Skipped: 0, Pending: 0, Inconclusive 1
    
    #>
        [CmdletBinding()]
        param(
            [Parameter(Mandatory = $false, ParameterSetName = "Inconclusive")][switch]$Inconclusive,
            [Parameter(Mandatory = $false, ParameterSetName = "Pending")][switch]$Pending,
            [Parameter(Mandatory = $false, ParameterSetName = "Skipped")][switch]$Skipped,
            [string]$Because
        )
    
        Assert-DescribeInProgress -CommandName Set-ItResult
    
        $result = $PSCmdlet.ParameterSetName
        $message = "It result set to $result$(if ($Because) { ", $Because" })"
        $data = @{
            Result  = $result
            Because = $Because
        }
        $errorRecord = New-PesterErrorRecord -Result $result  -Message $message -Data $data
        throw $errorRecord
    }
    
    function New-PesterErrorRecord {
        [CmdletBinding()]
        param(
            [Parameter(Mandatory = $true)]
            [string]$Result,
            [Parameter(Mandatory = $true)]
            [string]$Message,
            [string]$File,
            [string]$Line,
            [string]$LineText,
            [hashtable]$Data
        )
    
        $exception = New-Object Exception $Message
        $errorID = "PesterTest$Result"
        $errorCategory = [Management.Automation.ErrorCategory]::InvalidResult
    
        # we use ErrorRecord.TargetObject to pass structured information about the error to a reporting system.
        $targetObject = @{
            Message  = $Message
            Data     = $Data
            File     = $(if ($File -ne $null) {
                    $File
                }
                else {
                    $MyInvocation.ScriptName
                })
            Line     = $(if ($Line -ne $null) {
                    $Line
                }
                else {
                    $MyInvocation.ScriptLineNumber
                })
            LineText = $(if ($LineText -ne $null) {
                    $LineText
                }
                else {
                    $MyInvocation.Line
                }).TrimEnd($([System.Environment]::NewLine))
        }
    
        New-Object Management.Automation.ErrorRecord $exception, $errorID, $errorCategory, $targetObject
    }
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUAJ5Y8OAwBbb7yZ1FEhXOGcY/
    # j0eggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # e8FzXx858YxRnrFZURNWUQO9CucwDQYJKoZIhvcNAQEBBQAEggEAoUyAvmUEP8/g
    # cHQT1E/tJld30GDpOy0CVCx4z1rZ9jTOOO/u/vX8yWkJFhyuo0CYmLP6qO7ublvJ
    # Hq3T2v3PfZypZE1HyfxwD/35ji/0x3retpdhaaRDDwZHfcYaqLeRURCGIemVd6o1
    # JAi+SKHloo0ySHxZKKskfXOl8EH0Q58S//8cbKckgdw7Kfc9QeG5T+NZZnJP5gJC
    # IlCc0s0TIAa+tGLJySgZ/XY76np7o9e78VcLrZu5QXOYgp8pspO/2KV8aEOZ/bGr
    # kiCe3f/KAierzAMj5EyXrGs4NZJBXkiKbnM76gmDebX47VdO9yAL7QTPDkfmFH6t
    # cZxYmd5zAaGCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzQ0WjAjBgkqhkiG9w0BCQQx
    # FgQUb3Rnr08ylXK/gwVNGyiyHihGsEkwDQYJKoZIhvcNAQEBBQAEggEACbEjiubs
    # lm1FMDjLIJxW7fbngs6fNfOCSDnmlRzTGDhib1qM9m8L0JKoP0FIcXWbA7L5wczj
    # QYamX0uWme3aWUAv2XdMsY+t+jDHVK4m9wDM7kWWVpf34CmFFAONQFfudn8TPh/k
    # tzjOWqjge9r0PttoUGVN8o6mdUCMiGiC5CG/udHfjn3Ugy6vJu6tGLyk/i5xe1V+
    # V8+Ysv8NMs10g5Y7MzFPgdLR7s+QH+FwPaWLZGTFvsCrASLIZVP5yFCzrkyM2EgC
    # 0lKiDE3MtXLq8Ydwy9/e9yVsDaNsPXCx3kCd9sOg3gFN/2v398d1HvqYwlvotiCH
    # ViyjqeL7vAx+Sw==
    # SIG # End signature block
    
  • tools\Functions\SetupTeardown.ps1 Show
    function BeforeEach {
        <#
        .SYNOPSIS
            Defines a series of steps to perform at the beginning of every It block within
            the current Context or Describe block.
    
        .DESCRIPTION
            BeforeEach, AfterEach, BeforeAll, and AfterAll are unique in that they apply
            to the entire Context or Describe block, regardless of the order of the
            statements in the Context or Describe.  For a full description of this
            behavior, as well as how multiple BeforeEach or AfterEach blocks interact
            with each other, please refer to the about_BeforeEach_AfterEach help file.
    
        .LINK
            https://github.com/pester/Pester/wiki/BeforeEach-and-AfterEach
    
        .LINK
            about_BeforeEach_AfterEach
        #>
        [CmdletBinding()]
        param
        (
            # the scriptblock to execute
            [Parameter(Mandatory = $true,
                Position = 1)]
            [Scriptblock]
            $Scriptblock
        )
        Assert-DescribeInProgress -CommandName BeforeEach
    }
    
    function AfterEach {
        <#
        .SYNOPSIS
            Defines a series of steps to perform at the end of every It block within
            the current Context or Describe block.
    
        .DESCRIPTION
            BeforeEach, AfterEach, BeforeAll, and AfterAll are unique in that they apply
            to the entire Context or Describe block, regardless of the order of the
            statements in the Context or Describe.  For a full description of this
            behavior, as well as how multiple BeforeEach or AfterEach blocks interact
            with each other, please refer to the about_BeforeEach_AfterEach help file.
    
        .LINK
            https://github.com/pester/Pester/wiki/BeforeEach-and-AfterEach
    
        .LINK
            about_BeforeEach_AfterEach
        #>
        [CmdletBinding()]
        param
        (
            # the scriptblock to execute
            [Parameter(Mandatory = $true,
                Position = 1)]
            [Scriptblock]
            $Scriptblock
        )
        Assert-DescribeInProgress -CommandName AfterEach
    }
    
    function BeforeAll {
        <#
        .SYNOPSIS
            Defines a series of steps to perform at the beginning of the current Context
            or Describe block.
    
        .DESCRIPTION
            BeforeEach, AfterEach, BeforeAll, and AfterAll are unique in that they apply
            to the entire Context or Describe block, regardless of the order of the
            statements in the Context or Describe.
    
        .LINK
            https://github.com/pester/Pester/wiki/BeforeEach-and-AfterEach
    
        .LINK
            about_BeforeEach_AfterEach
        #>
        [CmdletBinding()]
        param
        (
            # the scriptblock to execute
            [Parameter(Mandatory = $true,
                Position = 1)]
            [Scriptblock]
            $Scriptblock
        )
        Assert-DescribeInProgress -CommandName BeforeAll
    }
    
    function AfterAll {
        <#
    .SYNOPSIS
        Defines a series of steps to perform at the end of the current Context
        or Describe block.
    
    .DESCRIPTION
        BeforeEach, AfterEach, BeforeAll, and AfterAll are unique in that they apply
        to the entire Context or Describe block, regardless of the order of the
        statements in the Context or Describe.
    
        .LINK
            https://github.com/pester/Pester/wiki/BeforeEach-and-AfterEach
    
        .LINK
        about_BeforeEach_AfterEach
    #>
        [CmdletBinding()]
        param
        (
            # the scriptblock to execute
            [Parameter(Mandatory = $true,
                Position = 1)]
            [Scriptblock]
            $Scriptblock
        )
        Assert-DescribeInProgress -CommandName AfterAll
    }
    
    function Invoke-TestCaseSetupBlocks {
        Invoke-Blocks -ScriptBlock $pester.GetTestCaseSetupBlocks()
    }
    
    function Invoke-TestCaseTeardownBlocks {
        Invoke-Blocks -ScriptBlock $pester.GetTestCaseTeardownBlocks()
    }
    
    function Invoke-TestGroupSetupBlocks {
        Invoke-Blocks -ScriptBlock $pester.GetCurrentTestGroupSetupBlocks()
    }
    
    function Invoke-TestGroupTeardownBlocks {
        Invoke-Blocks -ScriptBlock $pester.GetCurrentTestGroupTeardownBlocks()
    }
    
    function Invoke-Blocks {
        param ([scriptblock[]] $ScriptBlock)
    
        foreach ($block in $ScriptBlock) {
            if ($null -eq $block) {
                continue
            }
            $null = . $block
        }
    }
    
    function Add-SetupAndTeardown {
        param (
            [scriptblock] $ScriptBlock
        )
    
        if ($PSVersionTable.PSVersion.Major -le 2) {
            Add-SetupAndTeardownV2 -ScriptBlock $ScriptBlock
        }
        else {
            Add-SetupAndTeardownV3 -ScriptBlock $ScriptBlock
        }
    }
    
    function Add-SetupAndTeardownV3 {
        param (
            [scriptblock] $ScriptBlock
        )
    
        $pattern = '^(?:Before|After)(?:Each|All)$'
        $predicate = {
            param ([System.Management.Automation.Language.Ast] $Ast)
    
            $Ast -is [System.Management.Automation.Language.CommandAst] -and
            $Ast.CommandElements[0].ToString() -match $pattern -and
            $Ast.CommandElements[-1] -is [System.Management.Automation.Language.ScriptBlockExpressionAst]
        }
    
        $searchNestedBlocks = $false
    
        $calls = $ScriptBlock.Ast.FindAll($predicate, $searchNestedBlocks)
    
        foreach ($call in $calls) {
            # For some reason, calling ScriptBlockAst.GetScriptBlock() sometimes blows up due to failing semantics
            # checks, even though the code is perfectly valid.  So we'll poke around with reflection again to skip
            # that part and just call the internal ScriptBlock constructor that we need
    
            $iPmdProviderType = [scriptblock].Assembly.GetType('System.Management.Automation.Language.IParameterMetadataProvider')
    
            $flags = [System.Reflection.BindingFlags]'Instance, NonPublic'
            $constructor = [scriptblock].GetConstructor($flags, $null, [Type[]]@($iPmdProviderType, [bool]), $null)
    
            $block = $constructor.Invoke(@($call.CommandElements[-1].ScriptBlock, $false))
    
            Set-ScriptBlockScope -ScriptBlock $block -SessionState $pester.SessionState
            $commandName = $call.CommandElements[0].ToString()
            Add-SetupOrTeardownScriptBlock -CommandName $commandName -ScriptBlock $block
        }
    }
    
    function Add-SetupAndTeardownV2 {
        param (
            [scriptblock] $ScriptBlock
        )
    
        $codeText = $ScriptBlock.ToString()
        $tokens = @(ParseCodeIntoTokens -CodeText $codeText)
    
        for ($i = 0; $i -lt $tokens.Count; $i++) {
            $token = $tokens[$i]
            $type = $token.Type
            if ($type -eq [System.Management.Automation.PSTokenType]::Command -and
                (IsSetupOrTeardownCommand -CommandName $token.Content)) {
                $openBraceIndex, $closeBraceIndex = Get-BraceIndicesForCommand -Tokens $tokens -CommandIndex $i
    
                $block = Get-ScriptBlockFromTokens -Tokens $Tokens -OpenBraceIndex $openBraceIndex -CloseBraceIndex $closeBraceIndex -CodeText $codeText
                Add-SetupOrTeardownScriptBlock -CommandName $token.Content -ScriptBlock $block
    
                $i = $closeBraceIndex
            }
            elseif ($type -eq [System.Management.Automation.PSTokenType]::GroupStart) {
                # We don't want to parse Setup or Teardown commands in child scopes here, so anything
                # bounded by a GroupStart / GroupEnd token pair which is not immediately preceded by
                # a setup / teardown command name is ignored.
                $i = Get-GroupCloseTokenIndex -Tokens $tokens -GroupStartTokenIndex $i
            }
        }
    }
    
    function ParseCodeIntoTokens {
        param ([string] $CodeText)
    
        $parseErrors = $null
        $tokens = [System.Management.Automation.PSParser]::Tokenize($CodeText, [ref] $parseErrors)
    
        if ($parseErrors.Count -gt 0) {
            $currentScope = $pester.CurrentTestGroup.Hint
            if (-not $currentScope) {
                $currentScope = 'test group'
            }
            throw "The current $currentScope block contains syntax errors."
        }
    
        return $tokens
    }
    
    function IsSetupOrTeardownCommand {
        param ([string] $CommandName)
        return (IsSetupCommand -CommandName $CommandName) -or (IsTeardownCommand -CommandName $CommandName)
    }
    
    function IsSetupCommand {
        param ([string] $CommandName)
        return $CommandName -eq 'BeforeEach' -or $CommandName -eq 'BeforeAll'
    }
    
    function IsTeardownCommand {
        param ([string] $CommandName)
        return $CommandName -eq 'AfterEach' -or $CommandName -eq 'AfterAll'
    }
    
    function IsTestGroupCommand {
        param ([string] $CommandName)
        return $CommandName -eq 'BeforeAll' -or $CommandName -eq 'AfterAll'
    }
    
    function Get-BraceIndicesForCommand {
        param (
            [System.Management.Automation.PSToken[]] $Tokens,
            [int] $CommandIndex
        )
    
        $openingGroupTokenIndex = Get-GroupStartTokenForCommand -Tokens $Tokens -CommandIndex $CommandIndex
        $closingGroupTokenIndex = Get-GroupCloseTokenIndex -Tokens $Tokens -GroupStartTokenIndex $openingGroupTokenIndex
    
        return $openingGroupTokenIndex, $closingGroupTokenIndex
    }
    
    function Get-GroupStartTokenForCommand {
        param (
            [System.Management.Automation.PSToken[]] $Tokens,
            [int] $CommandIndex
        )
    
        $commandName = $Tokens[$CommandIndex].Content
    
        # gets ScriptBlock from positional parameter e.g. BeforeEach { <code> }
        if ($CommandIndex + 1 -lt $tokens.Count -and
            ($tokens[$CommandIndex + 1].Type -eq [System.Management.Automation.PSTokenType]::GroupStart -or
                $tokens[$CommandIndex + 1].Content -eq '{')) {
            return $CommandIndex + 1
        }
    
        # gets ScriptBlock from named parameter e.g. BeforeEach -ScriptBlock { <code> }
        if ($CommandIndex + 2 -lt $tokens.Count -and
            ($tokens[$CommandIndex + 2].Type -eq [System.Management.Automation.PSTokenType]::GroupStart -or
                $tokens[$CommandIndex + 2].Content -eq '{')) {
            return $CommandIndex + 2
        }
    
        throw "The $commandName command must be followed by the script block as the first argument or named parameter value."
    }
    
    & $SafeCommands['Add-Type'] -TypeDefinition @'
        namespace Pester
        {
            using System;
            using System.Management.Automation;
    
            public static class ClosingBraceFinder
            {
                public static int GetClosingBraceIndex(PSToken[] tokens, int startIndex)
                {
                    int groupLevel = 1;
                    int len = tokens.Length;
    
                    for (int i = startIndex + 1; i < len; i++)
                    {
                        PSTokenType type = tokens[i].Type;
                        if (type == PSTokenType.GroupStart)
                        {
                            groupLevel++;
                        }
                        else if (type == PSTokenType.GroupEnd)
                        {
                            groupLevel--;
    
                            if (groupLevel <= 0) { return i; }
                        }
                    }
    
                    return -1;
                }
            }
        }
    '@
    
    function Get-GroupCloseTokenIndex {
        param (
            [System.Management.Automation.PSToken[]] $Tokens,
            [int] $GroupStartTokenIndex
        )
    
        $closeIndex = [Pester.ClosingBraceFinder]::GetClosingBraceIndex($Tokens, $GroupStartTokenIndex)
    
        if ($closeIndex -lt 0) {
            throw 'No corresponding GroupEnd token was found.'
        }
    
        return $closeIndex
    }
    
    function Get-ScriptBlockFromTokens {
        param (
            [System.Management.Automation.PSToken[]] $Tokens,
            [int] $OpenBraceIndex,
            [int] $CloseBraceIndex,
            [string] $CodeText
        )
    
        $blockStart = $Tokens[$OpenBraceIndex + 1].Start
        $blockLength = $Tokens[$CloseBraceIndex].Start - $blockStart
        $setupOrTeardownCodeText = $codeText.Substring($blockStart, $blockLength)
    
        $scriptBlock = [scriptblock]::Create($setupOrTeardownCodeText)
        Set-ScriptBlockHint -Hint "Unbound ScriptBlock from Get-ScriptBlockFromTokens" -ScriptBlock $scriptBlock
        Set-ScriptBlockScope -ScriptBlock $scriptBlock -SessionState $pester.SessionState
    
        return $scriptBlock
    }
    
    function Add-SetupOrTeardownScriptBlock {
        param (
            [string] $CommandName,
            [scriptblock] $ScriptBlock
        )
    
        $Pester.AddSetupOrTeardownBlock($ScriptBlock, $CommandName)
    }
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUDdmQKUqreqBbIJ+b89cR10vk
    # tl2ggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # WMJmrH3zwizzpj2m5E/jWmQ+Y7gwDQYJKoZIhvcNAQEBBQAEggEAms0Yg53vH6v5
    # hAzu10XXz0QfJE501foB3eMvR2g6sYP31hlHSzh1DG0Xw2P8L6CTMX7+n4g4+RWC
    # sP70w4gxpgKrE7xMS1csxE0lfqDERLEK8rsf9DBR+MO7rVqKa34/rpCReAhpALcV
    # 27XFj7b2I/BbDt/B5epxTjWFsq1X5X5Dwc56HzUY7IfPIo+1i/mJw9UnmAudUs50
    # i3F6DQEQszW0vxK0aHciGrX7PFmYBAuiNLuDo3rPZEhfSJqbIU92Fb9Ruqf32L7C
    # R5ANJkGfAAI+NniYBJ+vCSqZs5SpKS89P0xaHk1Vr9qyGz656nwWXoGwnfPN7lGX
    # B7a53va/0aGCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzQ1WjAjBgkqhkiG9w0BCQQx
    # FgQUMyyhzCA04rDAg47w1v3AOiGG7acwDQYJKoZIhvcNAQEBBQAEggEASnHBxFli
    # MgX1AN9Ei+ec3JHQ+76goNnLgGT5n8MaCRl1Rn/FmgTmcpjgKtwcRs+KPmdvUmgf
    # c3DcVcC3tG7fVlAO08gGZYn0Bne3vbtehBsAPn8c7mxcbDOeTM3tmypvzS/CxRAJ
    # gGKJDYLkcSzepAK8vMzexkBl4YvkRz1hXLXDVX7i9TrtAhxAU7VEMf0zYJlxIpuh
    # JEnaDP3HWfA7AmaRKw0YmOrVnZhhqZNlbZ2YhOAJDvM5cgzmTfh3LM09G/pui4mA
    # WWIbiQu8MPF7PPCEs06wA8imEu29IikiaktpZ2BfYOWVgcmTiTGVrDKq2lry9OCD
    # 0z9rF/Lbcs/hLA==
    # SIG # End signature block
    
  • tools\Functions\TestDrive.ps1 Show
    #
    function New-TestDrive ([Switch]$PassThru, [string] $Path) {
        if ($Path -notmatch '\S') {
            $directory = New-RandomTempDirectory
        }
        else {
            if (-not (& $SafeCommands['Test-Path'] -Path $Path)) {
                $null = & $SafeCommands['New-Item'] -ItemType Container -Path $Path
            }
    
            $directory = & $SafeCommands['Get-Item'] $Path
        }
    
        $DriveName = "TestDrive"
    
        #setup the test drive
        if ( -not (& $SafeCommands['Test-Path'] "${DriveName}:\") ) {
            $null = & $SafeCommands['New-PSDrive'] -Name $DriveName -PSProvider FileSystem -Root $directory -Scope Global -Description "Pester test drive"
        }
    
        #publish the global TestDrive variable used in few places within the module
        if (-not (& $SafeCommands['Test-Path'] "Variable:Global:$DriveName")) {
            & $SafeCommands['New-Variable'] -Name $DriveName -Scope Global -Value $directory
        }
    
        if ( $PassThru ) {
            & $SafeCommands['Get-PSDrive'] -Name $DriveName
        }
    }
    
    
    function Clear-TestDrive ([String[]]$Exclude) {
        $Path = (& $SafeCommands['Get-PSDrive'] -Name TestDrive).Root
        if (& $SafeCommands['Test-Path'] -Path $Path ) {
    
            Remove-TestDriveSymbolicLinks -Path $Path
    
            #Get-ChildItem -Exclude did not seem to work with full paths
            & $SafeCommands['Get-ChildItem'] -Recurse -Path $Path |
                & $SafeCommands['Sort-Object'] -Descending  -Property "FullName" |
                & $SafeCommands['Where-Object'] { $Exclude -NotContains $_.FullName } |
                & $SafeCommands['Remove-Item'] -Force -Recurse
    
        }
    }
    
    function New-RandomTempDirectory {
        do {
            $tempPath = Get-TempDirectory
            $Path = & $SafeCommands['Join-Path'] -Path $tempPath -ChildPath ([Guid]::NewGuid())
        } until (-not (& $SafeCommands['Test-Path'] -Path $Path ))
    
        & $SafeCommands['New-Item'] -ItemType Container -Path $Path
    }
    
    function Get-TestDriveItem {
        <#
        .SYNOPSIS
        The Get-TestDriveItem cmdlet gets the item in Pester test drive.
    
        .DESCRIPTION
        The Get-TestDriveItem cmdlet gets the item in Pester test drive. It does not
        get the contents of the item at the location unless you use a wildcard
        character (*) to request all the contents of the item.
    
        The function Get-TestDriveItem is deprecated since Pester v. 4.0
        and will be deleted in the next major version of Pester.
    
        .PARAMETER Path
        Specifies the path to an item. The path need to be relative to TestDrive:.
        This cmdlet gets the item at the specified location. Wildcards are permitted.
        This parameter is required, but the parameter name ("Path") is optional.
    
        .EXAMPLE
    
        Get-TestDriveItem MyTestFolder\MyTestFile.txt
    
        This command returns the file MyTestFile.txt located in the folder MyTestFolder
        what is located under TestDrive.
    
        .LINK
        https://github.com/pester/Pester/wiki/TestDrive
        about_TestDrive
    #>
    
        #moved here from Pester.psm1
        param ([string]$Path)
    
        & $SafeCommands['Write-Warning'] -Message "The function Get-TestDriveItem is deprecated since Pester 4.0.0 and will be removed from Pester 5.0.0."
    
        Assert-DescribeInProgress -CommandName Get-TestDriveItem
        & $SafeCommands['Get-Item'] $(& $SafeCommands['Join-Path'] $TestDrive $Path )
    }
    
    function Get-TestDriveChildItem {
        $Path = (& $SafeCommands['Get-PSDrive'] -Name TestDrive).Root
        if (& $SafeCommands['Test-Path'] -Path $Path ) {
            & $SafeCommands['Get-ChildItem'] -Recurse -Path $Path
        }
    }
    
    function Remove-TestDriveSymbolicLinks ([String] $Path) {
    
        # remove symbolic links to work around problem with Remove-Item.
        # see https://github.com/PowerShell/PowerShell/issues/621
        #     https://github.com/pester/Pester/issues/1100
    
        # powershell 5 and higher
        # & $SafeCommands["Get-ChildItem"] -Recurse -Path $Path -Attributes "ReparsePoint" |
        #    % { $_.Delete() }
    
        # issue 621 was fixed before PowerShell 6.1
        # now there is an issue with calling the Delete method in recent (6.1) builds of PowerShell
        if ( (GetPesterPSVersion) -ge 6) {
            return
        }
    
        # powershell 2-compatible
        $reparsePoint = [System.IO.FileAttributes]::ReparsePoint
        & $SafeCommands["Get-ChildItem"] -Recurse -Path $Path |
            where-object { ($_.Attributes -band $reparsePoint) -eq $reparsePoint } |
            foreach-object { $_.Delete() }
    }
    
    function Remove-TestDrive {
    
        $DriveName = "TestDrive"
        $Drive = & $SafeCommands['Get-PSDrive'] -Name $DriveName -ErrorAction $script:IgnoreErrorPreference
        $Path = ($Drive).Root
    
    
        if ($pwd -like "$DriveName*" ) {
            #will staying in the test drive cause issues?
            #TODO review this
            & $SafeCommands['Write-Warning'] -Message "Your current path is set to ${pwd}:. You should leave ${DriveName}:\ before leaving Describe."
        }
    
        if ( $Drive ) {
            $Drive | & $SafeCommands['Remove-PSDrive'] -Force #This should fail explicitly as it impacts future pester runs
        }
    
        Remove-TestDriveSymbolicLinks -Path $Path
    
        if (& $SafeCommands['Test-Path'] -Path $Path) {
            & $SafeCommands['Remove-Item'] -Path $Path -Force -Recurse
        }
    
        if (& $SafeCommands['Get-Variable'] -Name $DriveName -Scope Global -ErrorAction $script:IgnoreErrorPreference) {
            & $SafeCommands['Remove-Variable'] -Scope Global -Name $DriveName -Force
        }
    }
    
    function Setup {
        <#
            .SYNOPSIS
            This command is included in the Pester Mocking framework for backwards compatibility.  You do not need to call it directly.
        #>
        param(
            [switch]$Dir,
            [switch]$File,
            $Path,
            $Content = "",
            [switch]$PassThru
        )
    
        Assert-DescribeInProgress -CommandName Setup
    
        $TestDriveName = & $SafeCommands['Get-PSDrive'] TestDrive |
            & $SafeCommands['Select-Object'] -ExpandProperty Root
    
        if ($Dir) {
            $item = & $SafeCommands['New-Item'] -Name $Path -Path "${TestDriveName}\" -Type Container -Force
        }
        if ($File) {
            $item = $Content | & $SafeCommands['New-Item'] -Name $Path -Path "${TestDriveName}\" -Type File -Force
        }
    
        if ($PassThru) {
            return $item
        }
    }
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUyUGUY/JTjY91htTx1uXhuXw5
    # gZuggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # 7d0HS9+dJ5C93+IdSA5ykrxlrNswDQYJKoZIhvcNAQEBBQAEggEAPGbZhFNsphJA
    # Bne8awHpMYcJXW0zNH2QzeL6yMNoqKKTtu9a70eglhJAqHWE84SzMiAneLQ7+kvC
    # edQm4xhbsIacUZ+fT/IQWA0WEwjq3x08sRWvYgmg6WHdIkfXtFc5d1+5jJgTT6ya
    # y4Z/wnfHhcA9FoR7D9NUlPBZ6xtGWFVApPLleggq5HyxtHdycRkzRhB5QGZs3prW
    # rHzdeINoYzD/+zVi6SyJQmf+l0VfF4XP0wwRuh6ustH2193mHKtBU+GMzfuAHeQm
    # Sj5STIokFe0u7NVnV2g1HwbjxgBXBTBdM2IRUNu2X+NpWHh3vr7b85dQK63iBHTr
    # oIqHHFdDLqGCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzQ1WjAjBgkqhkiG9w0BCQQx
    # FgQUfeROMpnsqdCS2isDvxGAP2cZ6lgwDQYJKoZIhvcNAQEBBQAEggEAE5/unbks
    # vFXCeBBFXG2BWCW8Va6UnSYta4yrRlgd4J0BEs8fHZ4ngjDN6Yw3TLM3Hp0dh5QK
    # /q4gSd3GctgzJFo6mPZhKD/BAv0mfm7XYs6FOYRLe7jwLuMfBGGQvgAGDVTleGkv
    # jdZ51xEaqS8fEoi45ukgp3r0JqGUWHXAYibwag5Ecv8hxQP0e3KmKa8zqi62N/eP
    # NIlJ5s6Clzum2JDwYi0LmTLAhXR99TwqeZzjGTcuVJ+FosJFyO41KLEaBJLV2/m/
    # I9GOxP7zj2Ily/SZ5zbTHsRZLusd4LGPPdxqBpqVDo8NajsNaBKk5LUFlga7ai+F
    # ywU1C4m1L2D3Ew==
    # SIG # End signature block
    
  • tools\Functions\TestRegistry.ps1 Show
    function New-TestRegistry {
        param(
            [Switch]
            $PassThru,
    
            [string]
            $Path
        )
    
        if ($Path -notmatch '\S') {
            $directory = New-RandomTempRegistry
        }
        else {
            if (-not (& $SafeCommands['Test-Path'] -Path $Path)) {
                # the pester registry root path HKCU:\Pester is created once
                # and then stays in place, in TestDrive we use system Temp folder,
                # but no such folder exists for registry so we create our own.
                # removing the folder after test run would be possible but we potentially
                # running into conflict with other instance of Pester that is running
                # so keeping it in place is a small price to pay for being able to run
                # parallel pester sessions easily.
                # Also don't use -Force parameter here
                # because that deletes the folder and creates a race condition see
                # https://github.com/pester/Pester/issues/1181
                $null = & $SafeCommands['New-Item'] -Path $Path
            }
    
            $directory = & $SafeCommands['Get-Item'] $Path
        }
    
        $DriveName = "TestRegistry"
        #setup the test drive
        if ( -not (& $SafeCommands['Test-Path'] "${DriveName}:\") ) {
            try {
                $null = & $SafeCommands['New-PSDrive'] -Name $DriveName -PSProvider Registry -Root $directory -Scope Global -Description "Pester test registry" -ErrorAction Stop
            }
            catch {
                if ($_.FullyQualifiedErrorId -like 'DriveAlreadyExists*') {
                    # it can happen that Test-Path reports false even though the drive
                    # exists. I don't know why but I see it in "Context Teardown fails"
                    # it would be possible to use Get-PsDrive directly for the test but it
                    # is about 10ms slower and we do it in every Describe and It so it would
                    # quickly add up
    
                    # so if that happens just ignore the error, the goal of this function is to
                    # create the testdrive and the testdrive already exists, so all is good.
                }
                else {
                    Write-Error $_ -ErrorAction 'Stop'
                }
            }
        }
    
        if ( $PassThru ) {
            & $SafeCommands['Get-PSDrive'] -Name $DriveName
        }
    }
    
    function Get-TestRegistryPath () {
        "Microsoft.PowerShell.Core\Registry::" + (& $SafeCommands['Get-PSDrive'] -Name TestRegistry -ErrorAction Stop).Root
    }
    
    function Clear-TestRegistry {
        param(
            [String[]]
            $Exclude
        )
    
        $path = Get-TestRegistryPath
    
        if ($null -ne $path -and (& $SafeCommands['Test-Path'] -Path $Path)) {
            #Get-ChildItem -Exclude did not seem to work with full paths
            & $SafeCommands['Get-ChildItem'] -Recurse -Path $Path |
                & $SafeCommands['Sort-Object'] -Descending  -Property 'PSPath' |
                & $SafeCommands['Where-Object'] { $Exclude -NotContains $_.PSPath } |
                & $SafeCommands['Remove-Item'] -Force -Recurse
        }
    }
    
    function Get-TestRegistryChildItem {
        $path = Get-TestRegistryPath
    
        & $SafeCommands['Get-ChildItem'] -Recurse -Path $path
    }
    
    function New-RandomTempRegistry {
        do {
            $tempPath = Get-TempRegistry
            $Path = & $SafeCommands['Join-Path'] -Path $tempPath -ChildPath ([Guid]::NewGuid())
        } until (-not (& $SafeCommands['Test-Path'] -Path $Path ))
    
        & $SafeCommands['New-Item'] -Path $Path
    }
    
    function Remove-TestRegistry {
        $DriveName = "TestRegistry"
        $Drive = & $SafeCommands['Get-PSDrive'] -Name $DriveName -ErrorAction $script:IgnoreErrorPreference
        if ($null -eq $Drive) {
            # the drive does not exist, someone must have removed it instead of us,
            # most likely a test that tests pester itself, so we just hope that the
            # one who removed this removed also the contents of it correctly
            return
        }
    
        $path = Get-TestRegistryPath
    
        if ($pwd -like "$DriveName*" ) {
            #will staying in the test drive cause issues?
            #TODO review this
            & $SafeCommands['Write-Warning'] -Message "Your current path is set to ${pwd}:. You should leave ${DriveName}:\ before leaving Describe."
        }
    
        if ( $Drive ) {
            $Drive | & $SafeCommands['Remove-PSDrive'] -Force #This should fail explicitly as it impacts future pester runs
        }
    
        if (& $SafeCommands['Test-Path'] -Path $path) {
            & $SafeCommands['Remove-Item'] -Path $path -Force -Recurse
        }
    
        if (& $SafeCommands['Get-Variable'] -Name $DriveName -Scope Global -ErrorAction $script:IgnoreErrorPreference) {
            & $SafeCommands['Remove-Variable'] -Scope Global -Name $DriveName -Force
        }
    }
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQU01W4BROFTOUnLdssbcAUiet+
    # q+qggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # 6PCjvMzEVvESnYFJ7ANsKCPAbU8wDQYJKoZIhvcNAQEBBQAEggEAPf8xX1VxPBqX
    # f8yguezcdZnJjIc8NXHhBnU3tJ+5rN0H0HuBId7DrM5zlA4gfj8oQTO7OeU4GISN
    # 2vYbp3m6pr7Qy9jMIDFHhFyxr6U6QBPnEfmKWwBx+5cfYM7fAydks7iIFOKr8qYd
    # fOgHvUT4DtzXyQs/LBXtt4KQyzFif7zzPp9zYA+W+Hi5J3g+HaDt7p1+jI2FoE3h
    # sINRDYopWNahrgWJrARSa06MNpFYYGLqHUEu21Itig58hEI24eXUXPjJY6yUYXbE
    # 7/bfBdfR5wMMODwVNk77p1jmNUKsgBfh9Bi+8upFjkx+ee/0lZ4foE1zJbC5FeHt
    # e+X/qKN0yKGCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzQ2WjAjBgkqhkiG9w0BCQQx
    # FgQU+QzI7XwIOztc9r4hvJSglvf0zFswDQYJKoZIhvcNAQEBBQAEggEANXGaDFJV
    # bfCYzioc7hHnVipGa8j6/H99t4eyZpIviX4oOddcp0GA8Kj9j8QGIJ/2WA2vSq7t
    # GfsY5b0ZEJIqgj/AYV8Mr6MieT0FAJv9Y7RtNIIQJhHtI8qB4bA7iXsLUt4N/UxA
    # 8oJdxuHzBle2lq/qNoCqQ6E2VYLl7Ozcg4H4yvdLMB8fw5+v0qR+MTeLoRbgdnnc
    # 24jC9FMTBt2J3j8wx9ybT367F02YXjucTVdZxxFbJ0v0tcDl3TPE3qfMX9UcpAo1
    # U9Qre2xFXbAG4luyQQOTrhiC9YFCTLUYTNAm2e2UHfkm/uoma7EK7HM4//bvwMEn
    # 50vJduusIBBREw==
    # SIG # End signature block
    
  • tools\Functions\TestResults.ps1 Show
    function Get-HumanTime($Seconds) {
        if ($Seconds -gt 0.99) {
            $time = [math]::Round($Seconds, 2)
            $unit = 's'
        }
        else {
            $time = [math]::Floor($Seconds * 1000)
            $unit = 'ms'
        }
        return "$time$unit"
    }
    
    function GetFullPath ([string]$Path) {
        $Folder = & $SafeCommands['Split-Path'] -Path $Path -Parent
        $File = & $SafeCommands['Split-Path'] -Path $Path -Leaf
    
        if ( -not ([String]::IsNullOrEmpty($Folder))) {
            $FolderResolved = & $SafeCommands['Resolve-Path'] -Path $Folder
        }
        else {
            $FolderResolved = & $SafeCommands['Resolve-Path'] -Path $ExecutionContext.SessionState.Path.CurrentFileSystemLocation
        }
    
        $Path = & $SafeCommands['Join-Path'] -Path $FolderResolved.ProviderPath -ChildPath $File
    
        return $Path
    }
    
    function Export-PesterResults {
        param (
            $PesterState,
            [string] $Path,
            [string] $Format
        )
    
        switch ($Format) {
            'NUnitXml' {
                Export-NUnitReport -PesterState $PesterState -Path $Path
            }
    
            default {
                throw "'$Format' is not a valid Pester export format."
            }
        }
    }
    function Export-NUnitReport {
        param (
            [parameter(Mandatory = $true, ValueFromPipeline = $true)]
            $PesterState,
    
            [parameter(Mandatory = $true)]
            [String]$Path
        )
    
        #the xmlwriter create method can resolve relatives paths by itself. but its current directory might
        #be different from what PowerShell sees as the current directory so I have to resolve the path beforehand
        #working around the limitations of Resolve-Path
    
        $Path = GetFullPath -Path $Path
    
        $settings = & $SafeCommands['New-Object'] -TypeName Xml.XmlWriterSettings -Property @{
            Indent              = $true
            NewLineOnAttributes = $false
        }
    
        $xmlFile = $null
        $xmlWriter = $null
        try {
            $xmlFile = [IO.File]::Create($Path)
            $xmlWriter = [Xml.XmlWriter]::Create($xmlFile, $settings)
    
            Write-NUnitReport -XmlWriter $xmlWriter -PesterState $PesterState
    
            $xmlWriter.Flush()
            $xmlFile.Flush()
        }
        finally {
            if ($null -ne $xmlWriter) {
                try {
                    $xmlWriter.Close()
                }
                catch {
                }
            }
            if ($null -ne $xmlFile) {
                try {
                    $xmlFile.Close()
                }
                catch {
                }
            }
        }
    }
    
    function Write-NUnitReport($PesterState, [System.Xml.XmlWriter] $XmlWriter) {
        # Write the XML Declaration
        $XmlWriter.WriteStartDocument($false)
    
        # Write Root Element
        $xmlWriter.WriteStartElement('test-results')
    
        Write-NUnitTestResultAttributes @PSBoundParameters
        Write-NUnitTestResultChildNodes @PSBoundParameters
    
        $XmlWriter.WriteEndElement()
    }
    
    function Write-NUnitTestResultAttributes($PesterState, [System.Xml.XmlWriter] $XmlWriter) {
        $XmlWriter.WriteAttributeString('xmlns', 'xsi', $null, 'http://www.w3.org/2001/XMLSchema-instance')
        $XmlWriter.WriteAttributeString('xsi', 'noNamespaceSchemaLocation', [Xml.Schema.XmlSchema]::InstanceNamespace , 'nunit_schema_2.5.xsd')
        $XmlWriter.WriteAttributeString('name', 'Pester')
        $XmlWriter.WriteAttributeString('total', ($PesterState.TotalCount - $PesterState.SkippedCount))
        $XmlWriter.WriteAttributeString('errors', '0')
        $XmlWriter.WriteAttributeString('failures', $PesterState.FailedCount)
        $XmlWriter.WriteAttributeString('not-run', '0')
        $XmlWriter.WriteAttributeString('inconclusive', $PesterState.PendingCount + $PesterState.InconclusiveCount)
        $XmlWriter.WriteAttributeString('ignored', $PesterState.SkippedCount)
        $XmlWriter.WriteAttributeString('skipped', '0')
        $XmlWriter.WriteAttributeString('invalid', '0')
        $date = & $SafeCommands['Get-Date']
        $XmlWriter.WriteAttributeString('date', (& $SafeCommands['Get-Date'] -Date $date -Format 'yyyy-MM-dd'))
        $XmlWriter.WriteAttributeString('time', (& $SafeCommands['Get-Date'] -Date $date -Format 'HH:mm:ss'))
    }
    
    function Write-NUnitTestResultChildNodes($PesterState, [System.Xml.XmlWriter] $XmlWriter) {
        Write-NUnitEnvironmentInformation @PSBoundParameters
        Write-NUnitCultureInformation @PSBoundParameters
    
        $suiteInfo = Get-TestSuiteInfo -TestSuite $PesterState -TestSuiteName $PesterState.TestSuiteName
    
        $XmlWriter.WriteStartElement('test-suite')
    
        Write-NUnitTestSuiteAttributes -TestSuiteInfo $suiteInfo -XmlWriter $XmlWriter
    
        $XmlWriter.WriteStartElement('results')
    
        foreach ($action in $PesterState.TestActions.Actions) {
            Write-NUnitTestSuiteElements -XmlWriter $XmlWriter -Node $action
        }
    
        $XmlWriter.WriteEndElement()
        $XmlWriter.WriteEndElement()
    }
    
    function Write-NUnitEnvironmentInformation($PesterState, [System.Xml.XmlWriter] $XmlWriter) {
        $XmlWriter.WriteStartElement('environment')
    
        $environment = Get-RunTimeEnvironment
        foreach ($keyValuePair in $environment.GetEnumerator()) {
            $XmlWriter.WriteAttributeString($keyValuePair.Name, $keyValuePair.Value)
        }
    
        $XmlWriter.WriteEndElement()
    }
    
    function Write-NUnitCultureInformation($PesterState, [System.Xml.XmlWriter] $XmlWriter) {
        $XmlWriter.WriteStartElement('culture-info')
    
        $XmlWriter.WriteAttributeString('current-culture', ([System.Threading.Thread]::CurrentThread.CurrentCulture).Name)
        $XmlWriter.WriteAttributeString('current-uiculture', ([System.Threading.Thread]::CurrentThread.CurrentUiCulture).Name)
    
        $XmlWriter.WriteEndElement()
    }
    
    function Write-NUnitTestSuiteElements($Node, [System.Xml.XmlWriter] $XmlWriter, [string] $Path) {
        $suiteInfo = Get-TestSuiteInfo $Node
    
        $XmlWriter.WriteStartElement('test-suite')
    
        Write-NUnitTestSuiteAttributes -TestSuiteInfo $suiteInfo -XmlWriter $XmlWriter
    
        $XmlWriter.WriteStartElement('results')
    
        $separator = if ($Path) {
            '.'
        }
        else {
            ''
        }
        $newName = if ($Node.Hint -ne 'Script') {
            $suiteInfo.Name
        }
        else {
            ''
        }
        $newPath = "${Path}${separator}${newName}"
    
        foreach ($action in $Node.Actions) {
            if ($action.Type -eq 'TestGroup') {
                Write-NUnitTestSuiteElements -Node $action -XmlWriter $XmlWriter -Path $newPath
            }
        }
    
        $suites = @(
            $Node.Actions |
                & $SafeCommands['Where-Object'] { $_.Type -eq 'TestCase' } |
                & $SafeCommands['Group-Object'] -Property ParameterizedSuiteName
        )
    
        foreach ($suite in $suites) {
            if ($suite.Name) {
                $parameterizedSuiteInfo = Get-ParameterizedTestSuiteInfo -TestSuiteGroup $suite
    
                $XmlWriter.WriteStartElement('test-suite')
    
                Write-NUnitTestSuiteAttributes -TestSuiteInfo $parameterizedSuiteInfo -TestSuiteType 'ParameterizedTest' -XmlWriter $XmlWriter -Path $newPath
    
                $XmlWriter.WriteStartElement('results')
            }
    
            foreach ($testCase in $suite.Group) {
                Write-NUnitTestCaseElement -TestResult $testCase -XmlWriter $XmlWriter -Path $newPath -ParameterizedSuiteName $suite.Name
            }
    
            if ($suite.Name) {
                $XmlWriter.WriteEndElement()
                $XmlWriter.WriteEndElement()
            }
        }
    
        $XmlWriter.WriteEndElement()
        $XmlWriter.WriteEndElement()
    }
    
    function Get-ParameterizedTestSuiteInfo ([Microsoft.PowerShell.Commands.GroupInfo] $TestSuiteGroup) {
        $node = & $SafeCommands['New-Object'] psobject -Property @{
            Name              = $TestSuiteGroup.Name
            TotalCount        = 0
            Time              = [timespan]0
            PassedCount       = 0
            FailedCount       = 0
            SkippedCount      = 0
            PendingCount      = 0
            InconclusiveCount = 0
        }
    
        foreach ($testCase in $TestSuiteGroup.Group) {
            $node.TotalCount++
    
            switch ($testCase.Result) {
                Passed {
                    $Node.PassedCount++; break;
                }
                Failed {
                    $Node.FailedCount++; break;
                }
                Skipped {
                    $Node.SkippedCount++; break;
                }
                Pending {
                    $Node.PendingCount++; break;
                }
                Inconclusive {
                    $Node.InconclusiveCount++; break;
                }
            }
    
            $Node.Time += $testCase.Time
        }
    
        return Get-TestSuiteInfo -TestSuite $node
    }
    
    function Get-TestSuiteInfo ($TestSuite, $TestSuiteName) {
        if (-not $PSBoundParameters.ContainsKey('TestSuiteName')) {
            $TestSuiteName = $TestSuite.Name
        }
    
        $suite = @{
            resultMessage = 'Failure'
            success       = if ($TestSuite.FailedCount -eq 0) {
                'True'
            }
            else {
                'False'
            }
            totalTime     = Convert-TimeSpan $TestSuite.Time
            name          = $TestSuiteName
            description   = $TestSuiteName
        }
    
        $suite.resultMessage = Get-GroupResult $TestSuite
        $suite
    }
    
    function Get-TestTime($tests) {
        [TimeSpan]$totalTime = 0;
        if ($tests) {
            foreach ($test in $tests) {
                $totalTime += $test.time
            }
        }
    
        Convert-TimeSpan -TimeSpan $totalTime
    }
    function Convert-TimeSpan {
        param (
            [Parameter(ValueFromPipeline = $true)]
            $TimeSpan
        )
        process {
            if ($TimeSpan) {
                [string][math]::round(([TimeSpan]$TimeSpan).totalseconds, 4)
            }
            else {
                '0'
            }
        }
    }
    function Get-TestSuccess($tests) {
        $result = $true
        if ($tests) {
            foreach ($test in $tests) {
                if (-not $test.Passed) {
                    $result = $false
                    break
                }
            }
        }
        [String]$result
    }
    function Write-NUnitTestSuiteAttributes($TestSuiteInfo, [string] $TestSuiteType = 'TestFixture', [System.Xml.XmlWriter] $XmlWriter, [string] $Path) {
        $name = $TestSuiteInfo.Name
    
        if ($TestSuiteType -eq 'ParameterizedTest' -and $Path) {
            $name = "$Path.$name"
        }
    
        $XmlWriter.WriteAttributeString('type', $TestSuiteType)
        $XmlWriter.WriteAttributeString('name', $name)
        $XmlWriter.WriteAttributeString('executed', 'True')
        $XmlWriter.WriteAttributeString('result', $TestSuiteInfo.resultMessage)
        $XmlWriter.WriteAttributeString('success', $TestSuiteInfo.success)
        $XmlWriter.WriteAttributeString('time', $TestSuiteInfo.totalTime)
        $XmlWriter.WriteAttributeString('asserts', '0')
        $XmlWriter.WriteAttributeString('description', $TestSuiteInfo.Description)
    }
    
    function Write-NUnitTestCaseElement($TestResult, [System.Xml.XmlWriter] $XmlWriter, [string] $ParameterizedSuiteName, [string] $Path) {
        $XmlWriter.WriteStartElement('test-case')
    
        Write-NUnitTestCaseAttributes -TestResult $TestResult -XmlWriter $XmlWriter -ParameterizedSuiteName $ParameterizedSuiteName -Path $Path
    
        $XmlWriter.WriteEndElement()
    }
    
    function Write-NUnitTestCaseAttributes($TestResult, [System.Xml.XmlWriter] $XmlWriter, [string] $ParameterizedSuiteName, [string] $Path) {
        $testName = $TestResult.Name
    
        if ($testName -eq $ParameterizedSuiteName) {
            $paramString = ''
            if ($null -ne $TestResult.Parameters) {
                $params = @(
                    foreach ($value in $TestResult.Parameters.Values) {
                        if ($null -eq $value) {
                            'null'
                        }
                        elseif ($value -is [string]) {
                            '"{0}"' -f $value
                        }
                        else {
                            #do not use .ToString() it uses the current culture settings
                            #and we need to use en-US culture, which [string] or .ToString([Globalization.CultureInfo]'en-us') uses
                            [string]$value
                        }
                    }
                )
    
                $paramString = $params -join ','
            }
    
            $testName = "$testName($paramString)"
        }
    
        $separator = if ($Path) {
            '.'
        }
        else {
            ''
        }
        $testName = "${Path}${separator}${testName}"
    
        $XmlWriter.WriteAttributeString('description', $TestResult.Name)
    
        $XmlWriter.WriteAttributeString('name', $testName)
        $XmlWriter.WriteAttributeString('time', (Convert-TimeSpan $TestResult.Time))
        $XmlWriter.WriteAttributeString('asserts', '0')
        $XmlWriter.WriteAttributeString('success', $TestResult.Passed)
    
        switch ($TestResult.Result) {
            Passed {
                $XmlWriter.WriteAttributeString('result', 'Success')
                $XmlWriter.WriteAttributeString('executed', 'True')
                break
            }
            Skipped {
                $XmlWriter.WriteAttributeString('result', 'Ignored')
                $XmlWriter.WriteAttributeString('executed', 'False')
                break
            }
    
            Pending {
                $XmlWriter.WriteAttributeString('result', 'Inconclusive')
                $XmlWriter.WriteAttributeString('executed', 'True')
                break
            }
            Inconclusive {
                $XmlWriter.WriteAttributeString('result', 'Inconclusive')
                $XmlWriter.WriteAttributeString('executed', 'True')
    
                if ($TestResult.FailureMessage) {
                    $XmlWriter.WriteStartElement('reason')
                    $xmlWriter.WriteElementString('message', $TestResult.FailureMessage)
                    $XmlWriter.WriteEndElement() # Close reason tag
                }
    
                break
            }
            Failed {
                $XmlWriter.WriteAttributeString('result', 'Failure')
                $XmlWriter.WriteAttributeString('executed', 'True')
                $XmlWriter.WriteStartElement('failure')
                $xmlWriter.WriteElementString('message', $TestResult.FailureMessage)
                $XmlWriter.WriteElementString('stack-trace', $TestResult.StackTrace)
                $XmlWriter.WriteEndElement() # Close failure tag
                break
            }
        }
    }
    function Get-RunTimeEnvironment() {
        # based on what we found during startup, use the appropriate cmdlet
        $computerName = $env:ComputerName
        $userName = $env:Username
        if ($null -ne $SafeCommands['Get-CimInstance']) {
            $osSystemInformation = (& $SafeCommands['Get-CimInstance'] Win32_OperatingSystem)
        }
        elseif ($null -ne $SafeCommands['Get-WmiObject']) {
            $osSystemInformation = (& $SafeCommands['Get-WmiObject'] Win32_OperatingSystem)
        }
        elseif ($IsMacOS -or $IsLinux) {
            $osSystemInformation = @{
                Name    = "Unknown"
                Version = "0.0.0.0"
            }
            try {
                if ($null -ne $SafeCommands['uname']) {
                    $osSystemInformation.Version = & $SafeCommands['uname'] -r
                    $osSystemInformation.Name = & $SafeCommands['uname'] -s
                    $computerName = & $SafeCommands['uname'] -n
                }
                if ($null -ne $SafeCommands['id']) {
                    $userName = & $SafeCommands['id'] -un
                }
            }
            catch {
                # well, we tried
            }
        }
        else {
            $osSystemInformation = @{
                Name    = "Unknown"
                Version = "0.0.0.0"
            }
        }
    
        if ( ($PSVersionTable.ContainsKey('PSEdition')) -and ($PSVersionTable.PSEdition -eq 'Core')) {
            $CLrVersion = "Unknown"
    
        }
        else {
            $CLrVersion = [string]$PSVersionTable.ClrVersion
        }
    
        @{
            'nunit-version' = '2.5.8.0'
            'os-version'    = $osSystemInformation.Version
            platform        = $osSystemInformation.Name
            cwd             = (& $SafeCommands['Get-Location']).Path #run path
            'machine-name'  = $computerName
            user            = $username
            'user-domain'   = $env:userDomain
            'clr-version'   = $CLrVersion
        }
    }
    
    function Exit-WithCode ($FailedCount) {
        $host.SetShouldExit($FailedCount)
    }
    
    function Get-GroupResult ($InputObject) {
        #I am not sure about the result precedence, and can't find any good source
        #TODO: Confirm this is the correct order of precedence
        if ($inputObject.FailedCount -gt 0) {
            return 'Failure'
        }
        if ($InputObject.SkippedCount -gt 0) {
            return 'Ignored'
        }
        if ($InputObject.PendingCount -gt 0) {
            return 'Inconclusive'
        }
        return 'Success'
    }
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUD1O6+9t5KdEOqYz5PnT8calI
    # LYWggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # 1RIU9DxoaFGq1HrqK759p7wJIZUwDQYJKoZIhvcNAQEBBQAEggEAZYhAnKv1vLZN
    # ym4kO/fBZY0eS9ZSJvEfD4t6UeamzV8CuHPZsfA9OB5wqqqchgXJ5AmwfpBViNhk
    # 1pAQSNvjIomp/7RzK1JTdMy00Oa04yzShKsv7Nvps7Oe1fKDCEmp8ZGWrfR5RXKS
    # iYwY0cX/8QRBx86PbI+IBw9aejDLR+D+06E+odMYe3beAHUbiGGB866Ryp3+RLqa
    # QA133aOV+IZfLW7VEoDHUMzXooeZam//RWH/wrmrSX6VdJkmhGmX1gsn8gSzf1bk
    # nte9+2EVby0fsWRu5ykMxQQOwq5msQFvI9nhEZmu/FtFws4lpeygBdQhR/9DRIv2
    # oulWXSIaeKGCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzQ3WjAjBgkqhkiG9w0BCQQx
    # FgQUGaLalQ/AYD1WUgsWoKa7brhJeSEwDQYJKoZIhvcNAQEBBQAEggEAlAi2z1ky
    # cDa3V5SSFlP5ICGB3bDFWJ9pDu9AcMF91AjHUYNwDH620DfP/+S4F2tQo3+Xk9X+
    # JxVZWFZq92GEkngTdf6JIWN9oOzQPXmGbZuiUfO204Pz57xSTRf6OOZdoBcIhjeP
    # 75TfG0GEzXEllI0nHSLBec2XeV+G5oJBxChXOLiQ6hJOl4NWRPwcMq2bZ7XS5lzX
    # eu/7m05eAvBiAOWP5zb1iUvvdG12ZCDcFBU3l9zVBncEXLFEyvIWuVk3BVVliHSF
    # 7nbIu/syXf6c9fRi2MQ5J2jIaFJ0s3JlzP0R+RG/zJIf9D4ud9R4T0qkQyghYcuP
    # kZ97fi5beA9pzg==
    # SIG # End signature block
    
  • tools\lib\Gherkin\core\Gherkin.dll Show
    md5: 2C960FFDCA31E06A82787FA28C264724 | sha1: 1DCC56BE43052A5CF31DD950DEB7E4B1983DFA00 | sha256: 7E1F108FAB00A283C01BA775B6EF2811829D86C0E59CE8EF8E19D946E3E34D96 | sha512: 1F629BD24BC3E038AE11351716EC0C8D52814988B1CA2F8C276ACA1DE0D5C8DA533D4096F93B431406038C67BE2A74065FBE87A7D2ABCDE925D47AE9BBB9520D
  • tools\lib\Gherkin\gherkin-languages.json Show
    {
      "af": {
        "and": [
          "* ",
          "En "
        ],
        "background": [
          "Agtergrond"
        ],
        "but": [
          "* ",
          "Maar "
        ],
        "examples": [
          "Voorbeelde"
        ],
        "feature": [
          "Funksie",
          "Besigheid Behoefte",
          "Vermoë"
        ],
        "given": [
          "* ",
          "Gegewe "
        ],
        "name": "Afrikaans",
        "native": "Afrikaans",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Voorbeeld",
          "Situasie"
        ],
        "scenarioOutline": [
          "Situasie Uiteensetting"
        ],
        "then": [
          "* ",
          "Dan "
        ],
        "when": [
          "* ",
          "Wanneer "
        ]
      },
      "am": {
        "and": [
          "* ",
          "Եվ "
        ],
        "background": [
          "Կոնտեքստ"
        ],
        "but": [
          "* ",
          "Բայց "
        ],
        "examples": [
          "Օրինակներ"
        ],
        "feature": [
          "Ֆունկցիոնալություն",
          "Հատկություն"
        ],
        "given": [
          "* ",
          "Դիցուք "
        ],
        "name": "Armenian",
        "native": "հայերեն",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Օրինակ",
          "Սցենար"
        ],
        "scenarioOutline": [
          "Սցենարի կառուցվացքը"
        ],
        "then": [
          "* ",
          "Ապա "
        ],
        "when": [
          "* ",
          "Եթե ",
          "Երբ "
        ]
      },
      "an": {
        "and": [
          "* ",
          "Y ",
          "E "
        ],
        "background": [
          "Antecedents"
        ],
        "but": [
          "* ",
          "Pero "
        ],
        "examples": [
          "Eixemplos"
        ],
        "feature": [
          "Caracteristica"
        ],
        "given": [
          "* ",
          "Dau ",
          "Dada ",
          "Daus ",
          "Dadas "
        ],
        "name": "Aragonese",
        "native": "Aragonés",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Eixemplo",
          "Caso"
        ],
        "scenarioOutline": [
          "Esquema del caso"
        ],
        "then": [
          "* ",
          "Alavez ",
          "Allora ",
          "Antonces "
        ],
        "when": [
          "* ",
          "Cuan "
        ]
      },
      "ar": {
        "and": [
          "* ",
          "و "
        ],
        "background": [
          "الخلفية"
        ],
        "but": [
          "* ",
          "لكن "
        ],
        "examples": [
          "امثلة"
        ],
        "feature": [
          "خاصية"
        ],
        "given": [
          "* ",
          "بفرض "
        ],
        "name": "Arabic",
        "native": "العربية",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "مثال",
          "سيناريو"
        ],
        "scenarioOutline": [
          "سيناريو مخطط"
        ],
        "then": [
          "* ",
          "اذاً ",
          "ثم "
        ],
        "when": [
          "* ",
          "متى ",
          "عندما "
        ]
      },
      "ast": {
        "and": [
          "* ",
          "Y ",
          "Ya "
        ],
        "background": [
          "Antecedentes"
        ],
        "but": [
          "* ",
          "Peru "
        ],
        "examples": [
          "Exemplos"
        ],
        "feature": [
          "Carauterística"
        ],
        "given": [
          "* ",
          "Dáu ",
          "Dada ",
          "Daos ",
          "Daes "
        ],
        "name": "Asturian",
        "native": "asturianu",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Exemplo",
          "Casu"
        ],
        "scenarioOutline": [
          "Esbozu del casu"
        ],
        "then": [
          "* ",
          "Entós "
        ],
        "when": [
          "* ",
          "Cuando "
        ]
      },
      "az": {
        "and": [
          "* ",
          "Və ",
          "Həm "
        ],
        "background": [
          "Keçmiş",
          "Kontekst"
        ],
        "but": [
          "* ",
          "Amma ",
          "Ancaq "
        ],
        "examples": [
          "Nümunələr"
        ],
        "feature": [
          "Özəllik"
        ],
        "given": [
          "* ",
          "Tutaq ki ",
          "Verilir "
        ],
        "name": "Azerbaijani",
        "native": "Azərbaycanca",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Nümunə",
          "Ssenari"
        ],
        "scenarioOutline": [
          "Ssenarinin strukturu"
        ],
        "then": [
          "* ",
          "O halda "
        ],
        "when": [
          "* ",
          "Əgər ",
          "Nə vaxt ki "
        ]
      },
      "bg": {
        "and": [
          "* ",
          "И "
        ],
        "background": [
          "Предистория"
        ],
        "but": [
          "* ",
          "Но "
        ],
        "examples": [
          "Примери"
        ],
        "feature": [
          "Функционалност"
        ],
        "given": [
          "* ",
          "Дадено "
        ],
        "name": "Bulgarian",
        "native": "български",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Пример",
          "Сценарий"
        ],
        "scenarioOutline": [
          "Рамка на сценарий"
        ],
        "then": [
          "* ",
          "То "
        ],
        "when": [
          "* ",
          "Когато "
        ]
      },
      "bm": {
        "and": [
          "* ",
          "Dan "
        ],
        "background": [
          "Latar Belakang"
        ],
        "but": [
          "* ",
          "Tetapi ",
          "Tapi "
        ],
        "examples": [
          "Contoh"
        ],
        "feature": [
          "Fungsi"
        ],
        "given": [
          "* ",
          "Diberi ",
          "Bagi "
        ],
        "name": "Malay",
        "native": "Bahasa Melayu",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Senario",
          "Situasi",
          "Keadaan"
        ],
        "scenarioOutline": [
          "Kerangka Senario",
          "Kerangka Situasi",
          "Kerangka Keadaan",
          "Garis Panduan Senario"
        ],
        "then": [
          "* ",
          "Maka ",
          "Kemudian "
        ],
        "when": [
          "* ",
          "Apabila "
        ]
      },
      "bs": {
        "and": [
          "* ",
          "I ",
          "A "
        ],
        "background": [
          "Pozadina"
        ],
        "but": [
          "* ",
          "Ali "
        ],
        "examples": [
          "Primjeri"
        ],
        "feature": [
          "Karakteristika"
        ],
        "given": [
          "* ",
          "Dato "
        ],
        "name": "Bosnian",
        "native": "Bosanski",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Primjer",
          "Scenariju",
          "Scenario"
        ],
        "scenarioOutline": [
          "Scenariju-obris",
          "Scenario-outline"
        ],
        "then": [
          "* ",
          "Zatim "
        ],
        "when": [
          "* ",
          "Kada "
        ]
      },
      "ca": {
        "and": [
          "* ",
          "I "
        ],
        "background": [
          "Rerefons",
          "Antecedents"
        ],
        "but": [
          "* ",
          "Però "
        ],
        "examples": [
          "Exemples"
        ],
        "feature": [
          "Característica",
          "Funcionalitat"
        ],
        "given": [
          "* ",
          "Donat ",
          "Donada ",
          "Atès ",
          "Atesa "
        ],
        "name": "Catalan",
        "native": "català",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Exemple",
          "Escenari"
        ],
        "scenarioOutline": [
          "Esquema de l'escenari"
        ],
        "then": [
          "* ",
          "Aleshores ",
          "Cal "
        ],
        "when": [
          "* ",
          "Quan "
        ]
      },
      "cs": {
        "and": [
          "* ",
          "A také ",
          "A "
        ],
        "background": [
          "Pozadí",
          "Kontext"
        ],
        "but": [
          "* ",
          "Ale "
        ],
        "examples": [
          "Příklady"
        ],
        "feature": [
          "Požadavek"
        ],
        "given": [
          "* ",
          "Pokud ",
          "Za předpokladu "
        ],
        "name": "Czech",
        "native": "Česky",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Příklad",
          "Scénář"
        ],
        "scenarioOutline": [
          "Náčrt Scénáře",
          "Osnova scénáře"
        ],
        "then": [
          "* ",
          "Pak "
        ],
        "when": [
          "* ",
          "Když "
        ]
      },
      "cy-GB": {
        "and": [
          "* ",
          "A "
        ],
        "background": [
          "Cefndir"
        ],
        "but": [
          "* ",
          "Ond "
        ],
        "examples": [
          "Enghreifftiau"
        ],
        "feature": [
          "Arwedd"
        ],
        "given": [
          "* ",
          "Anrhegedig a "
        ],
        "name": "Welsh",
        "native": "Cymraeg",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Enghraifft",
          "Scenario"
        ],
        "scenarioOutline": [
          "Scenario Amlinellol"
        ],
        "then": [
          "* ",
          "Yna "
        ],
        "when": [
          "* ",
          "Pryd "
        ]
      },
      "da": {
        "and": [
          "* ",
          "Og "
        ],
        "background": [
          "Baggrund"
        ],
        "but": [
          "* ",
          "Men "
        ],
        "examples": [
          "Eksempler"
        ],
        "feature": [
          "Egenskab"
        ],
        "given": [
          "* ",
          "Givet "
        ],
        "name": "Danish",
        "native": "dansk",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Eksempel",
          "Scenarie"
        ],
        "scenarioOutline": [
          "Abstrakt Scenario"
        ],
        "then": [
          "* ",
          "Så "
        ],
        "when": [
          "* ",
          "Når "
        ]
      },
      "de": {
        "and": [
          "* ",
          "Und "
        ],
        "background": [
          "Grundlage"
        ],
        "but": [
          "* ",
          "Aber "
        ],
        "examples": [
          "Beispiele"
        ],
        "feature": [
          "Funktionalität"
        ],
        "given": [
          "* ",
          "Angenommen ",
          "Gegeben sei ",
          "Gegeben seien "
        ],
        "name": "German",
        "native": "Deutsch",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Beispiel",
          "Szenario"
        ],
        "scenarioOutline": [
          "Szenariogrundriss"
        ],
        "then": [
          "* ",
          "Dann "
        ],
        "when": [
          "* ",
          "Wenn "
        ]
      },
      "el": {
        "and": [
          "* ",
          "Και "
        ],
        "background": [
          "Υπόβαθρο"
        ],
        "but": [
          "* ",
          "Αλλά "
        ],
        "examples": [
          "Παραδείγματα",
          "Σενάρια"
        ],
        "feature": [
          "Δυνατότητα",
          "Λειτουργία"
        ],
        "given": [
          "* ",
          "Δεδομένου "
        ],
        "name": "Greek",
        "native": "Ελληνικά",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Παράδειγμα",
          "Σενάριο"
        ],
        "scenarioOutline": [
          "Περιγραφή Σεναρίου",
          "Περίγραμμα Σεναρίου"
        ],
        "then": [
          "* ",
          "Τότε "
        ],
        "when": [
          "* ",
          "Όταν "
        ]
      },
      "em": {
        "and": [
          "* ",
          "😂"
        ],
        "background": [
          "💤"
        ],
        "but": [
          "* ",
          "😔"
        ],
        "examples": [
          "📓"
        ],
        "feature": [
          "📚"
        ],
        "given": [
          "* ",
          "😐"
        ],
        "name": "Emoji",
        "native": "😀",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "🥒",
          "📕"
        ],
        "scenarioOutline": [
          "📖"
        ],
        "then": [
          "* ",
          "🙏"
        ],
        "when": [
          "* ",
          "🎬"
        ]
      },
      "en": {
        "and": [
          "* ",
          "And "
        ],
        "background": [
          "Background"
        ],
        "but": [
          "* ",
          "But "
        ],
        "examples": [
          "Examples",
          "Scenarios"
        ],
        "feature": [
          "Feature",
          "Business Need",
          "Ability"
        ],
        "given": [
          "* ",
          "Given "
        ],
        "name": "English",
        "native": "English",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Example",
          "Scenario"
        ],
        "scenarioOutline": [
          "Scenario Outline",
          "Scenario Template"
        ],
        "then": [
          "* ",
          "Then "
        ],
        "when": [
          "* ",
          "When "
        ]
      },
      "en-Scouse": {
        "and": [
          "* ",
          "An "
        ],
        "background": [
          "Dis is what went down"
        ],
        "but": [
          "* ",
          "Buh "
        ],
        "examples": [
          "Examples"
        ],
        "feature": [
          "Feature"
        ],
        "given": [
          "* ",
          "Givun ",
          "Youse know when youse got "
        ],
        "name": "Scouse",
        "native": "Scouse",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "The thing of it is"
        ],
        "scenarioOutline": [
          "Wharrimean is"
        ],
        "then": [
          "* ",
          "Dun ",
          "Den youse gotta "
        ],
        "when": [
          "* ",
          "Wun ",
          "Youse know like when "
        ]
      },
      "en-au": {
        "and": [
          "* ",
          "Too right "
        ],
        "background": [
          "First off"
        ],
        "but": [
          "* ",
          "Yeah nah "
        ],
        "examples": [
          "You'll wanna"
        ],
        "feature": [
          "Pretty much"
        ],
        "given": [
          "* ",
          "Y'know "
        ],
        "name": "Australian",
        "native": "Australian",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Awww, look mate"
        ],
        "scenarioOutline": [
          "Reckon it's like"
        ],
        "then": [
          "* ",
          "But at the end of the day I reckon "
        ],
        "when": [
          "* ",
          "It's just unbelievable "
        ]
      },
      "en-lol": {
        "and": [
          "* ",
          "AN "
        ],
        "background": [
          "B4"
        ],
        "but": [
          "* ",
          "BUT "
        ],
        "examples": [
          "EXAMPLZ"
        ],
        "feature": [
          "OH HAI"
        ],
        "given": [
          "* ",
          "I CAN HAZ "
        ],
        "name": "LOLCAT",
        "native": "LOLCAT",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "MISHUN"
        ],
        "scenarioOutline": [
          "MISHUN SRSLY"
        ],
        "then": [
          "* ",
          "DEN "
        ],
        "when": [
          "* ",
          "WEN "
        ]
      },
      "en-old": {
        "and": [
          "* ",
          "Ond ",
          "7 "
        ],
        "background": [
          "Aer",
          "Ær"
        ],
        "but": [
          "* ",
          "Ac "
        ],
        "examples": [
          "Se the",
          "Se þe",
          "Se ðe"
        ],
        "feature": [
          "Hwaet",
          "Hwæt"
        ],
        "given": [
          "* ",
          "Thurh ",
          "Þurh ",
          "Ðurh "
        ],
        "name": "Old English",
        "native": "Englisc",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Swa"
        ],
        "scenarioOutline": [
          "Swa hwaer swa",
          "Swa hwær swa"
        ],
        "then": [
          "* ",
          "Tha ",
          "Þa ",
          "Ða ",
          "Tha the ",
          "Þa þe ",
          "Ða ðe "
        ],
        "when": [
          "* ",
          "Tha ",
          "Þa ",
          "Ða "
        ]
      },
      "en-pirate": {
        "and": [
          "* ",
          "Aye "
        ],
        "background": [
          "Yo-ho-ho"
        ],
        "but": [
          "* ",
          "Avast! "
        ],
        "examples": [
          "Dead men tell no tales"
        ],
        "feature": [
          "Ahoy matey!"
        ],
        "given": [
          "* ",
          "Gangway! "
        ],
        "name": "Pirate",
        "native": "Pirate",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Heave to"
        ],
        "scenarioOutline": [
          "Shiver me timbers"
        ],
        "then": [
          "* ",
          "Let go and haul "
        ],
        "when": [
          "* ",
          "Blimey! "
        ]
      },
      "eo": {
        "and": [
          "* ",
          "Kaj "
        ],
        "background": [
          "Fono"
        ],
        "but": [
          "* ",
          "Sed "
        ],
        "examples": [
          "Ekzemploj"
        ],
        "feature": [
          "Trajto"
        ],
        "given": [
          "* ",
          "Donitaĵo ",
          "Komence "
        ],
        "name": "Esperanto",
        "native": "Esperanto",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Ekzemplo",
          "Scenaro",
          "Kazo"
        ],
        "scenarioOutline": [
          "Konturo de la scenaro",
          "Skizo",
          "Kazo-skizo"
        ],
        "then": [
          "* ",
          "Do "
        ],
        "when": [
          "* ",
          "Se "
        ]
      },
      "es": {
        "and": [
          "* ",
          "Y ",
          "E "
        ],
        "background": [
          "Antecedentes"
        ],
        "but": [
          "* ",
          "Pero "
        ],
        "examples": [
          "Ejemplos"
        ],
        "feature": [
          "Característica"
        ],
        "given": [
          "* ",
          "Dado ",
          "Dada ",
          "Dados ",
          "Dadas "
        ],
        "name": "Spanish",
        "native": "español",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Ejemplo",
          "Escenario"
        ],
        "scenarioOutline": [
          "Esquema del escenario"
        ],
        "then": [
          "* ",
          "Entonces "
        ],
        "when": [
          "* ",
          "Cuando "
        ]
      },
      "et": {
        "and": [
          "* ",
          "Ja "
        ],
        "background": [
          "Taust"
        ],
        "but": [
          "* ",
          "Kuid "
        ],
        "examples": [
          "Juhtumid"
        ],
        "feature": [
          "Omadus"
        ],
        "given": [
          "* ",
          "Eeldades "
        ],
        "name": "Estonian",
        "native": "eesti keel",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Juhtum",
          "Stsenaarium"
        ],
        "scenarioOutline": [
          "Raamstjuhtum",
          "Raamstsenaarium"
        ],
        "then": [
          "* ",
          "Siis "
        ],
        "when": [
          "* ",
          "Kui "
        ]
      },
      "fa": {
        "and": [
          "* ",
          "و "
        ],
        "background": [
          "زمینه"
        ],
        "but": [
          "* ",
          "اما "
        ],
        "examples": [
          "نمونه ها"
        ],
        "feature": [
          "وِیژگی"
        ],
        "given": [
          "* ",
          "با فرض "
        ],
        "name": "Persian",
        "native": "فارسی",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "مثال",
          "سناریو"
        ],
        "scenarioOutline": [
          "الگوی سناریو"
        ],
        "then": [
          "* ",
          "آنگاه "
        ],
        "when": [
          "* ",
          "هنگامی "
        ]
      },
      "fi": {
        "and": [
          "* ",
          "Ja "
        ],
        "background": [
          "Tausta"
        ],
        "but": [
          "* ",
          "Mutta "
        ],
        "examples": [
          "Tapaukset"
        ],
        "feature": [
          "Ominaisuus"
        ],
        "given": [
          "* ",
          "Oletetaan "
        ],
        "name": "Finnish",
        "native": "suomi",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Tapaus"
        ],
        "scenarioOutline": [
          "Tapausaihio"
        ],
        "then": [
          "* ",
          "Niin "
        ],
        "when": [
          "* ",
          "Kun "
        ]
      },
      "fr": {
        "and": [
          "* ",
          "Et que ",
          "Et qu'",
          "Et "
        ],
        "background": [
          "Contexte"
        ],
        "but": [
          "* ",
          "Mais que ",
          "Mais qu'",
          "Mais "
        ],
        "examples": [
          "Exemples"
        ],
        "feature": [
          "Fonctionnalité"
        ],
        "given": [
          "* ",
          "Soit ",
          "Etant donné que ",
          "Etant donné qu'",
          "Etant donné ",
          "Etant donnée ",
          "Etant donnés ",
          "Etant données ",
          "Étant donné que ",
          "Étant donné qu'",
          "Étant donné ",
          "Étant donnée ",
          "Étant donnés ",
          "Étant données "
        ],
        "name": "French",
        "native": "français",
        "rule": [
          "Règle"
        ],
        "scenario": [
          "Exemple",
          "Scénario"
        ],
        "scenarioOutline": [
          "Plan du scénario",
          "Plan du Scénario"
        ],
        "then": [
          "* ",
          "Alors "
        ],
        "when": [
          "* ",
          "Quand ",
          "Lorsque ",
          "Lorsqu'"
        ]
      },
      "ga": {
        "and": [
          "* ",
          "Agus"
        ],
        "background": [
          "Cúlra"
        ],
        "but": [
          "* ",
          "Ach"
        ],
        "examples": [
          "Samplaí"
        ],
        "feature": [
          "Gné"
        ],
        "given": [
          "* ",
          "Cuir i gcás go",
          "Cuir i gcás nach",
          "Cuir i gcás gur",
          "Cuir i gcás nár"
        ],
        "name": "Irish",
        "native": "Gaeilge",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Sampla",
          "Cás"
        ],
        "scenarioOutline": [
          "Cás Achomair"
        ],
        "then": [
          "* ",
          "Ansin"
        ],
        "when": [
          "* ",
          "Nuair a",
          "Nuair nach",
          "Nuair ba",
          "Nuair nár"
        ]
      },
      "gj": {
        "and": [
          "* ",
          "અને "
        ],
        "background": [
          "બેકગ્રાઉન્ડ"
        ],
        "but": [
          "* ",
          "પણ "
        ],
        "examples": [
          "ઉદાહરણો"
        ],
        "feature": [
          "લક્ષણ",
          "વ્યાપાર જરૂર",
          "ક્ષમતા"
        ],
        "given": [
          "* ",
          "આપેલ છે "
        ],
        "name": "Gujarati",
        "native": "ગુજરાતી",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "ઉદાહરણ",
          "સ્થિતિ"
        ],
        "scenarioOutline": [
          "પરિદ્દશ્ય રૂપરેખા",
          "પરિદ્દશ્ય ઢાંચો"
        ],
        "then": [
          "* ",
          "પછી "
        ],
        "when": [
          "* ",
          "ક્યારે "
        ]
      },
      "gl": {
        "and": [
          "* ",
          "E "
        ],
        "background": [
          "Contexto"
        ],
        "but": [
          "* ",
          "Mais ",
          "Pero "
        ],
        "examples": [
          "Exemplos"
        ],
        "feature": [
          "Característica"
        ],
        "given": [
          "* ",
          "Dado ",
          "Dada ",
          "Dados ",
          "Dadas "
        ],
        "name": "Galician",
        "native": "galego",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Exemplo",
          "Escenario"
        ],
        "scenarioOutline": [
          "Esbozo do escenario"
        ],
        "then": [
          "* ",
          "Entón ",
          "Logo "
        ],
        "when": [
          "* ",
          "Cando "
        ]
      },
      "he": {
        "and": [
          "* ",
          "וגם "
        ],
        "background": [
          "רקע"
        ],
        "but": [
          "* ",
          "אבל "
        ],
        "examples": [
          "דוגמאות"
        ],
        "feature": [
          "תכונה"
        ],
        "given": [
          "* ",
          "בהינתן "
        ],
        "name": "Hebrew",
        "native": "עברית",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "דוגמא",
          "תרחיש"
        ],
        "scenarioOutline": [
          "תבנית תרחיש"
        ],
        "then": [
          "* ",
          "אז ",
          "אזי "
        ],
        "when": [
          "* ",
          "כאשר "
        ]
      },
      "hi": {
        "and": [
          "* ",
          "और ",
          "तथा "
        ],
        "background": [
          "पृष्ठभूमि"
        ],
        "but": [
          "* ",
          "पर ",
          "परन्तु ",
          "किन्तु "
        ],
        "examples": [
          "उदाहरण"
        ],
        "feature": [
          "रूप लेख"
        ],
        "given": [
          "* ",
          "अगर ",
          "यदि ",
          "चूंकि "
        ],
        "name": "Hindi",
        "native": "हिंदी",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "परिदृश्य"
        ],
        "scenarioOutline": [
          "परिदृश्य रूपरेखा"
        ],
        "then": [
          "* ",
          "तब ",
          "तदा "
        ],
        "when": [
          "* ",
          "जब ",
          "कदा "
        ]
      },
      "hr": {
        "and": [
          "* ",
          "I "
        ],
        "background": [
          "Pozadina"
        ],
        "but": [
          "* ",
          "Ali "
        ],
        "examples": [
          "Primjeri",
          "Scenariji"
        ],
        "feature": [
          "Osobina",
          "Mogućnost",
          "Mogucnost"
        ],
        "given": [
          "* ",
          "Zadan ",
          "Zadani ",
          "Zadano ",
          "Ukoliko "
        ],
        "name": "Croatian",
        "native": "hrvatski",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Primjer",
          "Scenarij"
        ],
        "scenarioOutline": [
          "Skica",
          "Koncept"
        ],
        "then": [
          "* ",
          "Onda "
        ],
        "when": [
          "* ",
          "Kada ",
          "Kad "
        ]
      },
      "ht": {
        "and": [
          "* ",
          "Ak ",
          "Epi ",
          "E "
        ],
        "background": [
          "Kontèks",
          "Istorik"
        ],
        "but": [
          "* ",
          "Men "
        ],
        "examples": [
          "Egzanp"
        ],
        "feature": [
          "Karakteristik",
          "Mak",
          "Fonksyonalite"
        ],
        "given": [
          "* ",
          "Sipoze ",
          "Sipoze ke ",
          "Sipoze Ke "
        ],
        "name": "Creole",
        "native": "kreyòl",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Senaryo"
        ],
        "scenarioOutline": [
          "Plan senaryo",
          "Plan Senaryo",
          "Senaryo deskripsyon",
          "Senaryo Deskripsyon",
          "Dyagram senaryo",
          "Dyagram Senaryo"
        ],
        "then": [
          "* ",
          "Lè sa a ",
          "Le sa a "
        ],
        "when": [
          "* ",
          "Lè ",
          "Le "
        ]
      },
      "hu": {
        "and": [
          "* ",
          "És "
        ],
        "background": [
          "Háttér"
        ],
        "but": [
          "* ",
          "De "
        ],
        "examples": [
          "Példák"
        ],
        "feature": [
          "Jellemző"
        ],
        "given": [
          "* ",
          "Amennyiben ",
          "Adott "
        ],
        "name": "Hungarian",
        "native": "magyar",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Példa",
          "Forgatókönyv"
        ],
        "scenarioOutline": [
          "Forgatókönyv vázlat"
        ],
        "then": [
          "* ",
          "Akkor "
        ],
        "when": [
          "* ",
          "Majd ",
          "Ha ",
          "Amikor "
        ]
      },
      "id": {
        "and": [
          "* ",
          "Dan "
        ],
        "background": [
          "Dasar"
        ],
        "but": [
          "* ",
          "Tapi "
        ],
        "examples": [
          "Contoh"
        ],
        "feature": [
          "Fitur"
        ],
        "given": [
          "* ",
          "Dengan "
        ],
        "name": "Indonesian",
        "native": "Bahasa Indonesia",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Skenario"
        ],
        "scenarioOutline": [
          "Skenario konsep"
        ],
        "then": [
          "* ",
          "Maka "
        ],
        "when": [
          "* ",
          "Ketika "
        ]
      },
      "is": {
        "and": [
          "* ",
          "Og "
        ],
        "background": [
          "Bakgrunnur"
        ],
        "but": [
          "* ",
          "En "
        ],
        "examples": [
          "Dæmi",
          "Atburðarásir"
        ],
        "feature": [
          "Eiginleiki"
        ],
        "given": [
          "* ",
          "Ef "
        ],
        "name": "Icelandic",
        "native": "Íslenska",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Atburðarás"
        ],
        "scenarioOutline": [
          "Lýsing Atburðarásar",
          "Lýsing Dæma"
        ],
        "then": [
          "* ",
          "Þá "
        ],
        "when": [
          "* ",
          "Þegar "
        ]
      },
      "it": {
        "and": [
          "* ",
          "E "
        ],
        "background": [
          "Contesto"
        ],
        "but": [
          "* ",
          "Ma "
        ],
        "examples": [
          "Esempi"
        ],
        "feature": [
          "Funzionalità"
        ],
        "given": [
          "* ",
          "Dato ",
          "Data ",
          "Dati ",
          "Date "
        ],
        "name": "Italian",
        "native": "italiano",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Esempio",
          "Scenario"
        ],
        "scenarioOutline": [
          "Schema dello scenario"
        ],
        "then": [
          "* ",
          "Allora "
        ],
        "when": [
          "* ",
          "Quando "
        ]
      },
      "ja": {
        "and": [
          "* ",
          "かつ"
        ],
        "background": [
          "背景"
        ],
        "but": [
          "* ",
          "しかし",
          "但し",
          "ただし"
        ],
        "examples": [
          "例",
          "サンプル"
        ],
        "feature": [
          "フィーチャ",
          "機能"
        ],
        "given": [
          "* ",
          "前提"
        ],
        "name": "Japanese",
        "native": "日本語",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "シナリオ"
        ],
        "scenarioOutline": [
          "シナリオアウトライン",
          "シナリオテンプレート",
          "テンプレ",
          "シナリオテンプレ"
        ],
        "then": [
          "* ",
          "ならば"
        ],
        "when": [
          "* ",
          "もし"
        ]
      },
      "jv": {
        "and": [
          "* ",
          "Lan "
        ],
        "background": [
          "Dasar"
        ],
        "but": [
          "* ",
          "Tapi ",
          "Nanging ",
          "Ananging "
        ],
        "examples": [
          "Conto",
          "Contone"
        ],
        "feature": [
          "Fitur"
        ],
        "given": [
          "* ",
          "Nalika ",
          "Nalikaning "
        ],
        "name": "Javanese",
        "native": "Basa Jawa",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Skenario"
        ],
        "scenarioOutline": [
          "Konsep skenario"
        ],
        "then": [
          "* ",
          "Njuk ",
          "Banjur "
        ],
        "when": [
          "* ",
          "Manawa ",
          "Menawa "
        ]
      },
      "ka": {
        "and": [
          "* ",
          "და"
        ],
        "background": [
          "კონტექსტი"
        ],
        "but": [
          "* ",
          "მაგ­რამ"
        ],
        "examples": [
          "მაგალითები"
        ],
        "feature": [
          "თვისება"
        ],
        "given": [
          "* ",
          "მოცემული"
        ],
        "name": "Georgian",
        "native": "ქართველი",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "მაგალითად",
          "სცენარის"
        ],
        "scenarioOutline": [
          "სცენარის ნიმუში"
        ],
        "then": [
          "* ",
          "მაშინ"
        ],
        "when": [
          "* ",
          "როდესაც"
        ]
      },
      "kn": {
        "and": [
          "* ",
          "ಮತ್ತು "
        ],
        "background": [
          "ಹಿನ್ನೆಲೆ"
        ],
        "but": [
          "* ",
          "ಆದರೆ "
        ],
        "examples": [
          "ಉದಾಹರಣೆಗಳು"
        ],
        "feature": [
          "ಹೆಚ್ಚಳ"
        ],
        "given": [
          "* ",
          "ನೀಡಿದ "
        ],
        "name": "Kannada",
        "native": "ಕನ್ನಡ",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "ಉದಾಹರಣೆ",
          "ಕಥಾಸಾರಾಂಶ"
        ],
        "scenarioOutline": [
          "ವಿವರಣೆ"
        ],
        "then": [
          "* ",
          "ನಂತರ "
        ],
        "when": [
          "* ",
          "ಸ್ಥಿತಿಯನ್ನು "
        ]
      },
      "ko": {
        "and": [
          "* ",
          "그리고"
        ],
        "background": [
          "배경"
        ],
        "but": [
          "* ",
          "하지만",
          "단"
        ],
        "examples": [
          "예"
        ],
        "feature": [
          "기능"
        ],
        "given": [
          "* ",
          "조건",
          "먼저"
        ],
        "name": "Korean",
        "native": "한국어",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "시나리오"
        ],
        "scenarioOutline": [
          "시나리오 개요"
        ],
        "then": [
          "* ",
          "그러면"
        ],
        "when": [
          "* ",
          "만일",
          "만약"
        ]
      },
      "lt": {
        "and": [
          "* ",
          "Ir "
        ],
        "background": [
          "Kontekstas"
        ],
        "but": [
          "* ",
          "Bet "
        ],
        "examples": [
          "Pavyzdžiai",
          "Scenarijai",
          "Variantai"
        ],
        "feature": [
          "Savybė"
        ],
        "given": [
          "* ",
          "Duota "
        ],
        "name": "Lithuanian",
        "native": "lietuvių kalba",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Pavyzdys",
          "Scenarijus"
        ],
        "scenarioOutline": [
          "Scenarijaus šablonas"
        ],
        "then": [
          "* ",
          "Tada "
        ],
        "when": [
          "* ",
          "Kai "
        ]
      },
      "lu": {
        "and": [
          "* ",
          "an ",
          "a "
        ],
        "background": [
          "Hannergrond"
        ],
        "but": [
          "* ",
          "awer ",
          "mä "
        ],
        "examples": [
          "Beispiller"
        ],
        "feature": [
          "Funktionalitéit"
        ],
        "given": [
          "* ",
          "ugeholl "
        ],
        "name": "Luxemburgish",
        "native": "Lëtzebuergesch",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Beispill",
          "Szenario"
        ],
        "scenarioOutline": [
          "Plang vum Szenario"
        ],
        "then": [
          "* ",
          "dann "
        ],
        "when": [
          "* ",
          "wann "
        ]
      },
      "lv": {
        "and": [
          "* ",
          "Un "
        ],
        "background": [
          "Konteksts",
          "Situācija"
        ],
        "but": [
          "* ",
          "Bet "
        ],
        "examples": [
          "Piemēri",
          "Paraugs"
        ],
        "feature": [
          "Funkcionalitāte",
          "Fīča"
        ],
        "given": [
          "* ",
          "Kad "
        ],
        "name": "Latvian",
        "native": "latviešu",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Piemērs",
          "Scenārijs"
        ],
        "scenarioOutline": [
          "Scenārijs pēc parauga"
        ],
        "then": [
          "* ",
          "Tad "
        ],
        "when": [
          "* ",
          "Ja "
        ]
      },
      "mk-Cyrl": {
        "and": [
          "* ",
          "И "
        ],
        "background": [
          "Контекст",
          "Содржина"
        ],
        "but": [
          "* ",
          "Но "
        ],
        "examples": [
          "Примери",
          "Сценарија"
        ],
        "feature": [
          "Функционалност",
          "Бизнис потреба",
          "Можност"
        ],
        "given": [
          "* ",
          "Дадено ",
          "Дадена "
        ],
        "name": "Macedonian",
        "native": "Македонски",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Пример",
          "Сценарио",
          "На пример"
        ],
        "scenarioOutline": [
          "Преглед на сценарија",
          "Скица",
          "Концепт"
        ],
        "then": [
          "* ",
          "Тогаш "
        ],
        "when": [
          "* ",
          "Кога "
        ]
      },
      "mk-Latn": {
        "and": [
          "* ",
          "I "
        ],
        "background": [
          "Kontekst",
          "Sodrzhina"
        ],
        "but": [
          "* ",
          "No "
        ],
        "examples": [
          "Primeri",
          "Scenaria"
        ],
        "feature": [
          "Funkcionalnost",
          "Biznis potreba",
          "Mozhnost"
        ],
        "given": [
          "* ",
          "Dadeno ",
          "Dadena "
        ],
        "name": "Macedonian (Latin)",
        "native": "Makedonski (Latinica)",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Scenario",
          "Na primer"
        ],
        "scenarioOutline": [
          "Pregled na scenarija",
          "Skica",
          "Koncept"
        ],
        "then": [
          "* ",
          "Togash "
        ],
        "when": [
          "* ",
          "Koga "
        ]
      },
      "mn": {
        "and": [
          "* ",
          "Мөн ",
          "Тэгээд "
        ],
        "background": [
          "Агуулга"
        ],
        "but": [
          "* ",
          "Гэхдээ ",
          "Харин "
        ],
        "examples": [
          "Тухайлбал"
        ],
        "feature": [
          "Функц",
          "Функционал"
        ],
        "given": [
          "* ",
          "Өгөгдсөн нь ",
          "Анх "
        ],
        "name": "Mongolian",
        "native": "монгол",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Сценар"
        ],
        "scenarioOutline": [
          "Сценарын төлөвлөгөө"
        ],
        "then": [
          "* ",
          "Тэгэхэд ",
          "Үүний дараа "
        ],
        "when": [
          "* ",
          "Хэрэв "
        ]
      },
      "nl": {
        "and": [
          "* ",
          "En "
        ],
        "background": [
          "Achtergrond"
        ],
        "but": [
          "* ",
          "Maar "
        ],
        "examples": [
          "Voorbeelden"
        ],
        "feature": [
          "Functionaliteit"
        ],
        "given": [
          "* ",
          "Gegeven ",
          "Stel "
        ],
        "name": "Dutch",
        "native": "Nederlands",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Voorbeeld",
          "Scenario"
        ],
        "scenarioOutline": [
          "Abstract Scenario"
        ],
        "then": [
          "* ",
          "Dan "
        ],
        "when": [
          "* ",
          "Als ",
          "Wanneer "
        ]
      },
      "no": {
        "and": [
          "* ",
          "Og "
        ],
        "background": [
          "Bakgrunn"
        ],
        "but": [
          "* ",
          "Men "
        ],
        "examples": [
          "Eksempler"
        ],
        "feature": [
          "Egenskap"
        ],
        "given": [
          "* ",
          "Gitt "
        ],
        "name": "Norwegian",
        "native": "norsk",
        "rule": [
          "Regel"
        ],
        "scenario": [
          "Eksempel",
          "Scenario"
        ],
        "scenarioOutline": [
          "Scenariomal",
          "Abstrakt Scenario"
        ],
        "then": [
          "* ",
          "Så "
        ],
        "when": [
          "* ",
          "Når "
        ]
      },
      "pa": {
        "and": [
          "* ",
          "ਅਤੇ "
        ],
        "background": [
          "ਪਿਛੋਕੜ"
        ],
        "but": [
          "* ",
          "ਪਰ "
        ],
        "examples": [
          "ਉਦਾਹਰਨਾਂ"
        ],
        "feature": [
          "ਖਾਸੀਅਤ",
          "ਮੁਹਾਂਦਰਾ",
          "ਨਕਸ਼ ਨੁਹਾਰ"
        ],
        "given": [
          "* ",
          "ਜੇਕਰ ",
          "ਜਿਵੇਂ ਕਿ "
        ],
        "name": "Panjabi",
        "native": "ਪੰਜਾਬੀ",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "ਉਦਾਹਰਨ",
          "ਪਟਕਥਾ"
        ],
        "scenarioOutline": [
          "ਪਟਕਥਾ ਢਾਂਚਾ",
          "ਪਟਕਥਾ ਰੂਪ ਰੇਖਾ"
        ],
        "then": [
          "* ",
          "ਤਦ "
        ],
        "when": [
          "* ",
          "ਜਦੋਂ "
        ]
      },
      "pl": {
        "and": [
          "* ",
          "Oraz ",
          "I "
        ],
        "background": [
          "Założenia"
        ],
        "but": [
          "* ",
          "Ale "
        ],
        "examples": [
          "Przykłady"
        ],
        "feature": [
          "Właściwość",
          "Funkcja",
          "Aspekt",
          "Potrzeba biznesowa"
        ],
        "given": [
          "* ",
          "Zakładając ",
          "Mając ",
          "Zakładając, że "
        ],
        "name": "Polish",
        "native": "polski",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Przykład",
          "Scenariusz"
        ],
        "scenarioOutline": [
          "Szablon scenariusza"
        ],
        "then": [
          "* ",
          "Wtedy "
        ],
        "when": [
          "* ",
          "Jeżeli ",
          "Jeśli ",
          "Gdy ",
          "Kiedy "
        ]
      },
      "pt": {
        "and": [
          "* ",
          "E "
        ],
        "background": [
          "Contexto",
          "Cenário de Fundo",
          "Cenario de Fundo",
          "Fundo"
        ],
        "but": [
          "* ",
          "Mas "
        ],
        "examples": [
          "Exemplos",
          "Cenários",
          "Cenarios"
        ],
        "feature": [
          "Funcionalidade",
          "Característica",
          "Caracteristica"
        ],
        "given": [
          "* ",
          "Dado ",
          "Dada ",
          "Dados ",
          "Dadas "
        ],
        "name": "Portuguese",
        "native": "português",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Exemplo",
          "Cenário",
          "Cenario"
        ],
        "scenarioOutline": [
          "Esquema do Cenário",
          "Esquema do Cenario",
          "Delineação do Cenário",
          "Delineacao do Cenario"
        ],
        "then": [
          "* ",
          "Então ",
          "Entao "
        ],
        "when": [
          "* ",
          "Quando "
        ]
      },
      "ro": {
        "and": [
          "* ",
          "Si ",
          "Și ",
          "Şi "
        ],
        "background": [
          "Context"
        ],
        "but": [
          "* ",
          "Dar "
        ],
        "examples": [
          "Exemple"
        ],
        "feature": [
          "Functionalitate",
          "Funcționalitate",
          "Funcţionalitate"
        ],
        "given": [
          "* ",
          "Date fiind ",
          "Dat fiind ",
          "Dată fiind",
          "Dati fiind ",
          "Dați fiind ",
          "Daţi fiind "
        ],
        "name": "Romanian",
        "native": "română",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Exemplu",
          "Scenariu"
        ],
        "scenarioOutline": [
          "Structura scenariu",
          "Structură scenariu"
        ],
        "then": [
          "* ",
          "Atunci "
        ],
        "when": [
          "* ",
          "Cand ",
          "Când "
        ]
      },
      "ru": {
        "and": [
          "* ",
          "И ",
          "К тому же ",
          "Также "
        ],
        "background": [
          "Предыстория",
          "Контекст"
        ],
        "but": [
          "* ",
          "Но ",
          "А ",
          "Иначе "
        ],
        "examples": [
          "Примеры"
        ],
        "feature": [
          "Функция",
          "Функциональность",
          "Функционал",
          "Свойство"
        ],
        "given": [
          "* ",
          "Допустим ",
          "Дано ",
          "Пусть "
        ],
        "name": "Russian",
        "native": "русский",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Пример",
          "Сценарий"
        ],
        "scenarioOutline": [
          "Структура сценария"
        ],
        "then": [
          "* ",
          "То ",
          "Затем ",
          "Тогда "
        ],
        "when": [
          "* ",
          "Когда ",
          "Если "
        ]
      },
      "sk": {
        "and": [
          "* ",
          "A ",
          "A tiež ",
          "A taktiež ",
          "A zároveň "
        ],
        "background": [
          "Pozadie"
        ],
        "but": [
          "* ",
          "Ale "
        ],
        "examples": [
          "Príklady"
        ],
        "feature": [
          "Požiadavka",
          "Funkcia",
          "Vlastnosť"
        ],
        "given": [
          "* ",
          "Pokiaľ ",
          "Za predpokladu "
        ],
        "name": "Slovak",
        "native": "Slovensky",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Príklad",
          "Scenár"
        ],
        "scenarioOutline": [
          "Náčrt Scenáru",
          "Náčrt Scenára",
          "Osnova Scenára"
        ],
        "then": [
          "* ",
          "Tak ",
          "Potom "
        ],
        "when": [
          "* ",
          "Keď ",
          "Ak "
        ]
      },
      "sl": {
        "and": [
          "In ",
          "Ter "
        ],
        "background": [
          "Kontekst",
          "Osnova",
          "Ozadje"
        ],
        "but": [
          "Toda ",
          "Ampak ",
          "Vendar "
        ],
        "examples": [
          "Primeri",
          "Scenariji"
        ],
        "feature": [
          "Funkcionalnost",
          "Funkcija",
          "Možnosti",
          "Moznosti",
          "Lastnost",
          "Značilnost"
        ],
        "given": [
          "Dano ",
          "Podano ",
          "Zaradi ",
          "Privzeto "
        ],
        "name": "Slovenian",
        "native": "Slovenski",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Primer",
          "Scenarij"
        ],
        "scenarioOutline": [
          "Struktura scenarija",
          "Skica",
          "Koncept",
          "Oris scenarija",
          "Osnutek"
        ],
        "then": [
          "Nato ",
          "Potem ",
          "Takrat "
        ],
        "when": [
          "Ko ",
          "Ce ",
          "Če ",
          "Kadar "
        ]
      },
      "sr-Cyrl": {
        "and": [
          "* ",
          "И "
        ],
        "background": [
          "Контекст",
          "Основа",
          "Позадина"
        ],
        "but": [
          "* ",
          "Али "
        ],
        "examples": [
          "Примери",
          "Сценарији"
        ],
        "feature": [
          "Функционалност",
          "Могућност",
          "Особина"
        ],
        "given": [
          "* ",
          "За дато ",
          "За дате ",
          "За дати "
        ],
        "name": "Serbian",
        "native": "Српски",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Пример",
          "Сценарио",
          "Пример"
        ],
        "scenarioOutline": [
          "Структура сценарија",
          "Скица",
          "Концепт"
        ],
        "then": [
          "* ",
          "Онда "
        ],
        "when": [
          "* ",
          "Када ",
          "Кад "
        ]
      },
      "sr-Latn": {
        "and": [
          "* ",
          "I "
        ],
        "background": [
          "Kontekst",
          "Osnova",
          "Pozadina"
        ],
        "but": [
          "* ",
          "Ali "
        ],
        "examples": [
          "Primeri",
          "Scenariji"
        ],
        "feature": [
          "Funkcionalnost",
          "Mogućnost",
          "Mogucnost",
          "Osobina"
        ],
        "given": [
          "* ",
          "Za dato ",
          "Za date ",
          "Za dati "
        ],
        "name": "Serbian (Latin)",
        "native": "Srpski (Latinica)",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Scenario",
          "Primer"
        ],
        "scenarioOutline": [
          "Struktura scenarija",
          "Skica",
          "Koncept"
        ],
        "then": [
          "* ",
          "Onda "
        ],
        "when": [
          "* ",
          "Kada ",
          "Kad "
        ]
      },
      "sv": {
        "and": [
          "* ",
          "Och "
        ],
        "background": [
          "Bakgrund"
        ],
        "but": [
          "* ",
          "Men "
        ],
        "examples": [
          "Exempel"
        ],
        "feature": [
          "Egenskap"
        ],
        "given": [
          "* ",
          "Givet "
        ],
        "name": "Swedish",
        "native": "Svenska",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Scenario"
        ],
        "scenarioOutline": [
          "Abstrakt Scenario",
          "Scenariomall"
        ],
        "then": [
          "* ",
          "Så "
        ],
        "when": [
          "* ",
          "När "
        ]
      },
      "ta": {
        "and": [
          "* ",
          "மேலும்  ",
          "மற்றும் "
        ],
        "background": [
          "பின்னணி"
        ],
        "but": [
          "* ",
          "ஆனால்  "
        ],
        "examples": [
          "எடுத்துக்காட்டுகள்",
          "காட்சிகள்",
          "நிலைமைகளில்"
        ],
        "feature": [
          "அம்சம்",
          "வணிக தேவை",
          "திறன்"
        ],
        "given": [
          "* ",
          "கொடுக்கப்பட்ட "
        ],
        "name": "Tamil",
        "native": "தமிழ்",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "உதாரணமாக",
          "காட்சி"
        ],
        "scenarioOutline": [
          "காட்சி சுருக்கம்",
          "காட்சி வார்ப்புரு"
        ],
        "then": [
          "* ",
          "அப்பொழுது "
        ],
        "when": [
          "* ",
          "எப்போது "
        ]
      },
      "th": {
        "and": [
          "* ",
          "และ "
        ],
        "background": [
          "แนวคิด"
        ],
        "but": [
          "* ",
          "แต่ "
        ],
        "examples": [
          "ชุดของตัวอย่าง",
          "ชุดของเหตุการณ์"
        ],
        "feature": [
          "โครงหลัก",
          "ความต้องการทางธุรกิจ",
          "ความสามารถ"
        ],
        "given": [
          "* ",
          "กำหนดให้ "
        ],
        "name": "Thai",
        "native": "ไทย",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "เหตุการณ์"
        ],
        "scenarioOutline": [
          "สรุปเหตุการณ์",
          "โครงสร้างของเหตุการณ์"
        ],
        "then": [
          "* ",
          "ดังนั้น "
        ],
        "when": [
          "* ",
          "เมื่อ "
        ]
      },
      "tl": {
        "and": [
          "* ",
          "మరియు "
        ],
        "background": [
          "నేపథ్యం"
        ],
        "but": [
          "* ",
          "కాని "
        ],
        "examples": [
          "ఉదాహరణలు"
        ],
        "feature": [
          "గుణము"
        ],
        "given": [
          "* ",
          "చెప్పబడినది "
        ],
        "name": "Telugu",
        "native": "తెలుగు",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "ఉదాహరణ",
          "సన్నివేశం"
        ],
        "scenarioOutline": [
          "కథనం"
        ],
        "then": [
          "* ",
          "అప్పుడు "
        ],
        "when": [
          "* ",
          "ఈ పరిస్థితిలో "
        ]
      },
      "tlh": {
        "and": [
          "* ",
          "'ej ",
          "latlh "
        ],
        "background": [
          "mo'"
        ],
        "but": [
          "* ",
          "'ach ",
          "'a "
        ],
        "examples": [
          "ghantoH",
          "lutmey"
        ],
        "feature": [
          "Qap",
          "Qu'meH 'ut",
          "perbogh",
          "poQbogh malja'",
          "laH"
        ],
        "given": [
          "* ",
          "ghu' noblu' ",
          "DaH ghu' bejlu' "
        ],
        "name": "Klingon",
        "native": "tlhIngan",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "lut"
        ],
        "scenarioOutline": [
          "lut chovnatlh"
        ],
        "then": [
          "* ",
          "vaj "
        ],
        "when": [
          "* ",
          "qaSDI' "
        ]
      },
      "tr": {
        "and": [
          "* ",
          "Ve "
        ],
        "background": [
          "Geçmiş"
        ],
        "but": [
          "* ",
          "Fakat ",
          "Ama "
        ],
        "examples": [
          "Örnekler"
        ],
        "feature": [
          "Özellik"
        ],
        "given": [
          "* ",
          "Diyelim ki "
        ],
        "name": "Turkish",
        "native": "Türkçe",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Örnek",
          "Senaryo"
        ],
        "scenarioOutline": [
          "Senaryo taslağı"
        ],
        "then": [
          "* ",
          "O zaman "
        ],
        "when": [
          "* ",
          "Eğer ki "
        ]
      },
      "tt": {
        "and": [
          "* ",
          "Һәм ",
          "Вә "
        ],
        "background": [
          "Кереш"
        ],
        "but": [
          "* ",
          "Ләкин ",
          "Әмма "
        ],
        "examples": [
          "Үрнәкләр",
          "Мисаллар"
        ],
        "feature": [
          "Мөмкинлек",
          "Үзенчәлеклелек"
        ],
        "given": [
          "* ",
          "Әйтик "
        ],
        "name": "Tatar",
        "native": "Татарча",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Сценарий"
        ],
        "scenarioOutline": [
          "Сценарийның төзелеше"
        ],
        "then": [
          "* ",
          "Нәтиҗәдә "
        ],
        "when": [
          "* ",
          "Әгәр "
        ]
      },
      "uk": {
        "and": [
          "* ",
          "І ",
          "А також ",
          "Та "
        ],
        "background": [
          "Передумова"
        ],
        "but": [
          "* ",
          "Але "
        ],
        "examples": [
          "Приклади"
        ],
        "feature": [
          "Функціонал"
        ],
        "given": [
          "* ",
          "Припустимо ",
          "Припустимо, що ",
          "Нехай ",
          "Дано "
        ],
        "name": "Ukrainian",
        "native": "Українська",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Приклад",
          "Сценарій"
        ],
        "scenarioOutline": [
          "Структура сценарію"
        ],
        "then": [
          "* ",
          "То ",
          "Тоді "
        ],
        "when": [
          "* ",
          "Якщо ",
          "Коли "
        ]
      },
      "ur": {
        "and": [
          "* ",
          "اور "
        ],
        "background": [
          "پس منظر"
        ],
        "but": [
          "* ",
          "لیکن "
        ],
        "examples": [
          "مثالیں"
        ],
        "feature": [
          "صلاحیت",
          "کاروبار کی ضرورت",
          "خصوصیت"
        ],
        "given": [
          "* ",
          "اگر ",
          "بالفرض ",
          "فرض کیا "
        ],
        "name": "Urdu",
        "native": "اردو",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "منظرنامہ"
        ],
        "scenarioOutline": [
          "منظر نامے کا خاکہ"
        ],
        "then": [
          "* ",
          "پھر ",
          "تب "
        ],
        "when": [
          "* ",
          "جب "
        ]
      },
      "uz": {
        "and": [
          "* ",
          "Ва "
        ],
        "background": [
          "Тарих"
        ],
        "but": [
          "* ",
          "Лекин ",
          "Бирок ",
          "Аммо "
        ],
        "examples": [
          "Мисоллар"
        ],
        "feature": [
          "Функционал"
        ],
        "given": [
          "* ",
          "Агар "
        ],
        "name": "Uzbek",
        "native": "Узбекча",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Сценарий"
        ],
        "scenarioOutline": [
          "Сценарий структураси"
        ],
        "then": [
          "* ",
          "Унда "
        ],
        "when": [
          "* ",
          "Агар "
        ]
      },
      "vi": {
        "and": [
          "* ",
          "Và "
        ],
        "background": [
          "Bối cảnh"
        ],
        "but": [
          "* ",
          "Nhưng "
        ],
        "examples": [
          "Dữ liệu"
        ],
        "feature": [
          "Tính năng"
        ],
        "given": [
          "* ",
          "Biết ",
          "Cho "
        ],
        "name": "Vietnamese",
        "native": "Tiếng Việt",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "Tình huống",
          "Kịch bản"
        ],
        "scenarioOutline": [
          "Khung tình huống",
          "Khung kịch bản"
        ],
        "then": [
          "* ",
          "Thì "
        ],
        "when": [
          "* ",
          "Khi "
        ]
      },
      "zh-CN": {
        "and": [
          "* ",
          "而且",
          "并且",
          "同时"
        ],
        "background": [
          "背景"
        ],
        "but": [
          "* ",
          "但是"
        ],
        "examples": [
          "例子"
        ],
        "feature": [
          "功能"
        ],
        "given": [
          "* ",
          "假如",
          "假设",
          "假定"
        ],
        "name": "Chinese simplified",
        "native": "简体中文",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "场景",
          "剧本"
        ],
        "scenarioOutline": [
          "场景大纲",
          "剧本大纲"
        ],
        "then": [
          "* ",
          "那么"
        ],
        "when": [
          "* ",
          "当"
        ]
      },
      "zh-TW": {
        "and": [
          "* ",
          "而且",
          "並且",
          "同時"
        ],
        "background": [
          "背景"
        ],
        "but": [
          "* ",
          "但是"
        ],
        "examples": [
          "例子"
        ],
        "feature": [
          "功能"
        ],
        "given": [
          "* ",
          "假如",
          "假設",
          "假定"
        ],
        "name": "Chinese traditional",
        "native": "繁體中文",
        "rule": [
          "Rule"
        ],
        "scenario": [
          "場景",
          "劇本"
        ],
        "scenarioOutline": [
          "場景大綱",
          "劇本大綱"
        ],
        "then": [
          "* ",
          "那麼"
        ],
        "when": [
          "* ",
          "當"
        ]
      }
    }
    
  • tools\lib\Gherkin\legacy\Gherkin.dll Show
    md5: 92615D24CFBBBF4ADF905EABDF8A4B05 | sha1: 38481D6FF335556133C8349E83F99FF94E058D13 | sha256: 1D44069F3B38CEE04B7BE181F0A5DCD67EC536F3309F1838ED9D03032C820327 | sha512: D8AB995F2DE33AA052581B86E3EBD76260E29B206F519AA81512030408946A4FCA34559AE280A845D36826869B7C4CD45165BBA0B526003D8C9A1D2BB746D769
  • tools\lib\Gherkin\legacy\Newtonsoft.Json.dll Show
    md5: D3C90915030F4FB48BA75943042D378D | sha1: 6C683D8A5A8B3A6D317A40865D536F8DC4FCD764 | sha256: 105C55D60D854A3F2CD2C360D65A9B9B6C16DA5B0740E3364DF33BD0274A7C68 | sha512: CFD8FB13D469D2342C244C2914671954C5446C41FCAD38088F630EDB4D60995E1DEFD8C60405DD2CAB34A35FF01366EFE3371F7E1A921FCB2CEFD78B5E658454
  • tools\LICENSE
  • tools\nunit_schema_2.5.xsd
  • tools\Pester.psd1 Show
    @{
    
        # Script module or binary module file associated with this manifest.
        ModuleToProcess   = 'Pester.psm1'
    
        # Version number of this module.
        ModuleVersion     = '4.7.0'
    
        # ID used to uniquely identify this module
        GUID              = 'a699dea5-2c73-4616-a270-1f7abb777e71'
    
        # Author of this module
        Author            = 'Pester Team'
    
        # Company or vendor of this module
        CompanyName       = 'Pester'
    
        # Copyright statement for this module
        Copyright         = 'Copyright (c) 2019 by Pester Team, licensed under Apache 2.0 License.'
    
        # Description of the functionality provided by this module
        Description       = 'Pester provides a framework for running BDD style Tests to execute and validate PowerShell commands inside of PowerShell and offers a powerful set of Mocking Functions that allow tests to mimic and mock the functionality of any command inside of a piece of PowerShell code being tested. Pester tests can execute any command or script that is accessible to a pester test file. This can include functions, Cmdlets, Modules and scripts. Pester can be run in ad hoc style in a console or it can be integrated into the Build scripts of a Continuous Integration system.'
    
        # Minimum version of the Windows PowerShell engine required by this module
        PowerShellVersion = '2.0'
    
        TypesToProcess    = @('.\Functions\Gherkin.types.ps1xml')
    
        # Functions to export from this module
        FunctionsToExport = @(
            'Describe'
            'Context'
            'It'
            'Should'
            'Mock'
            'Assert-MockCalled'
            'Assert-VerifiableMock'
            'Assert-VerifiableMocks'
            'New-Fixture'
            'Get-TestDriveItem'
            'Invoke-Pester'
            'Setup'
            'In'
            'InModuleScope'
            'Invoke-Mock'
            'BeforeEach'
            'AfterEach'
            'BeforeAll'
            'AfterAll'
            'Get-MockDynamicParameter'
            'Set-DynamicParameterVariable'
            'Set-TestInconclusive'
            'Set-ItResult'
            'SafeGetCommand'
            'New-PesterOption'
            'New-MockObject'
            'Add-AssertionOperator'
            'Get-ShouldOperator'
    
            # Gherkin Support:
            'Invoke-Gherkin'
            'Find-GherkinStep'
            'GherkinStep'
            'BeforeEachFeature'
            'AfterEachFeature'
            'BeforeEachScenario'
            'AfterEachScenario'
        )
    
        # # Cmdlets to export from this module
        # CmdletsToExport = '*'
    
        # Variables to export from this module
        VariablesToExport = @(
            'Path'
            'TagFilter'
            'ExcludeTagFilter'
            'TestNameFilter'
            'TestResult'
            'CurrentContext'
            'CurrentDescribe'
            'CurrentTest'
            'SessionState'
            'CommandCoverage'
            'BeforeEach'
            'AfterEach'
            'Strict'
        )
    
        # # Aliases to export from this module
        AliasesToExport   = @(
            'Given'
            'When'
            'Then'
            'And'
            'But'
    
            'Add-ShouldOperator'
        )
    
    
        # List of all modules packaged with this module
        # ModuleList = @()
    
        # List of all files packaged with this module
        # FileList = @()
    
        PrivateData       = @{
            # PSData is module packaging and gallery metadata embedded in PrivateData
            # It's for rebuilding PowerShellGet (and PoshCode) NuGet-style packages
            # We had to do this because it's the only place we're allowed to extend the manifest
            # https://connect.microsoft.com/PowerShell/feedback/details/421837
            PSData = @{
                # The primary categorization of this module (from the TechNet Gallery tech tree).
                Category     = "Scripting Techniques"
    
                # Keyword tags to help users find this module via navigations and search.
                Tags         = @('powershell', 'unit_testing', 'bdd', 'tdd', 'mocking', 'PSEdition_Core', 'PSEdition_Desktop')
    
                # The web address of an icon which can be used in galleries to represent this module
                IconUri      = 'https://raw.githubusercontent.com/pester/Pester/master/images/pester.PNG'
    
                # The web address of this module's project or support homepage.
                ProjectUri   = "https://github.com/Pester/Pester"
    
                # The web address of this module's license. Points to a page that's embeddable and linkable.
                LicenseUri   = "https://www.apache.org/licenses/LICENSE-2.0.html"
    
                # Release notes for this particular version of the module
                ReleaseNotes = 'https://github.com/pester/Pester/releases/tag/4.7.0'
    
                # Prerelease string of this module
                Prerelease   = ''
            }
        }
    
        # HelpInfo URI of this module
        # HelpInfoURI = ''
    
        # Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
        # DefaultCommandPrefix = ''
    
    }
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUGQIQ+s/+BUYPQ6YgWdq66cQP
    # QY+ggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # jt2b5JAmp7uCtF2FLN7weUFFG/8wDQYJKoZIhvcNAQEBBQAEggEAf5VH/w+idVsi
    # 9N0CyqV1C5gpy+9mTvH+Cno353BFeOXzWysXqsRWirdA5ghufwcLEiITgHYrU9N3
    # ywJ4UBIDHGGQgROCDvhKymvxx734iymb55e/A8w/OrSXAU0XtvJw7BVXPPgdsq6D
    # SNTuL2i8wDaX+/okyME2SM44mIcwY41Js0KMEXVns/AUbC5d4kEYFGpHgjc1g4UQ
    # i6tGa2Z3FDhTIuc8OiPjan7Zjdn5S6nU0PRRXBPlOKDw2GslFij9QwnGaQIn7TWv
    # Ui9up2wMqupx8UDOcrVHf1xZWoc7zpPsoRBan10NHBpktnEKZD/jazzLFnux+ikA
    # GCWmGaRG46GCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzE4WjAjBgkqhkiG9w0BCQQx
    # FgQUxqH49hHwB9FM3R6EefUekqkoh4EwDQYJKoZIhvcNAQEBBQAEggEAjKY+lazT
    # RyIz+FPnHcjQtGkLpyKKBu8fx1T8YGeq5QlLjGM20EBJZNRlGNAZiv0R1cKVoDCv
    # 6d1ChNEvlXXjzJW1xnopUO+0F8MP5e49WdvA1dKhizP9O29wYrliYCcVdU2HasFe
    # MHEQU88BrIIqjvjHlmsL4lJEWVI9hzAVQNGylkKGLeZziEMxmIbfiDVzRRQBtKp/
    # 0sbjwcxSVSfEm5e95edcOJxQHn62hIIiXtBCVn/827R/Fb/E6HtJpwMqZR//MOA9
    # ujTnEB/7Ji8P+o+66Gs7m9YF6s/wyATbucjf7Jd6aXz4h/ixiA7upDvwDpojIIM9
    # CILX/9NIwFyEkg==
    # SIG # End signature block
    
  • tools\Pester.psm1 Show
    if ($PSVersionTable.PSVersion.Major -ge 3) {
        $script:IgnoreErrorPreference = 'Ignore'
        $outNullModule = 'Microsoft.PowerShell.Core'
        $outHostModule = 'Microsoft.PowerShell.Core'
    }
    else {
        $script:IgnoreErrorPreference = 'SilentlyContinue'
        $outNullModule = 'Microsoft.PowerShell.Utility'
        $outHostModule = $null
    }
    
    # Tried using $ExecutionState.InvokeCommand.GetCmdlet() here, but it does not trigger module auto-loading the way
    # Get-Command does.  Since this is at import time, before any mocks have been defined, that's probably acceptable.
    # If someone monkeys with Get-Command before they import Pester, they may break something.
    
    # The -All parameter is required when calling Get-Command to ensure that PowerShell can find the command it is
    # looking for. Otherwise, if you have modules loaded that define proxy cmdlets or that have cmdlets with the same
    # name as the safe cmdlets, Get-Command will return null.
    $safeCommandLookupParameters = @{
        CommandType = [System.Management.Automation.CommandTypes]::Cmdlet
        ErrorAction = [System.Management.Automation.ActionPreference]::Stop
    }
    
    if ($PSVersionTable.PSVersion.Major -gt 2) {
        $safeCommandLookupParameters['All'] = $true
    }
    
    $script:SafeCommands = @{
        'Add-Member'           = Get-Command -Name Add-Member           -Module Microsoft.PowerShell.Utility    @safeCommandLookupParameters
        'Add-Type'             = Get-Command -Name Add-Type             -Module Microsoft.PowerShell.Utility    @safeCommandLookupParameters
        'Compare-Object'       = Get-Command -Name Compare-Object       -Module Microsoft.PowerShell.Utility    @safeCommandLookupParameters
        'Export-ModuleMember'  = Get-Command -Name Export-ModuleMember  -Module Microsoft.PowerShell.Core       @safeCommandLookupParameters
        'ForEach-Object'       = Get-Command -Name ForEach-Object       -Module Microsoft.PowerShell.Core       @safeCommandLookupParameters
        'Format-Table'         = Get-Command -Name Format-Table         -Module Microsoft.PowerShell.Utility    @safeCommandLookupParameters
        'Get-Alias'            = Get-Command -Name Get-Alias            -Module Microsoft.PowerShell.Utility    @safeCommandLookupParameters
        'Get-ChildItem'        = Get-Command -Name Get-ChildItem        -Module Microsoft.PowerShell.Management @safeCommandLookupParameters
        'Get-Command'          = Get-Command -Name Get-Command          -Module Microsoft.PowerShell.Core       @safeCommandLookupParameters
        'Get-Content'          = Get-Command -Name Get-Content          -Module Microsoft.PowerShell.Management @safeCommandLookupParameters
        'Get-Date'             = Get-Command -Name Get-Date             -Module Microsoft.PowerShell.Utility    @safeCommandLookupParameters
        'Get-Item'             = Get-Command -Name Get-Item             -Module Microsoft.PowerShell.Management @safeCommandLookupParameters
        'Get-ItemProperty'     = Get-Command -Name Get-ItemProperty     -Module Microsoft.PowerShell.Management @safeCommandLookupParameters
        'Get-Location'         = Get-Command -Name Get-Location         -Module Microsoft.PowerShell.Management @safeCommandLookupParameters
        'Get-Member'           = Get-Command -Name Get-Member           -Module Microsoft.PowerShell.Utility    @safeCommandLookupParameters
        'Get-Module'           = Get-Command -Name Get-Module           -Module Microsoft.PowerShell.Core       @safeCommandLookupParameters
        'Get-PSDrive'          = Get-Command -Name Get-PSDrive          -Module Microsoft.PowerShell.Management @safeCommandLookupParameters
        'Get-PSCallStack'      = Get-Command -Name Get-PSCallStack      -Module Microsoft.PowerShell.Utility    @safeCommandLookupParameters
        'Get-Unique'           = Get-Command -Name Get-Unique           -Module Microsoft.PowerShell.Utility    @safeCommandLookupParameters
        'Get-Variable'         = Get-Command -Name Get-Variable         -Module Microsoft.PowerShell.Utility    @safeCommandLookupParameters
        'Group-Object'         = Get-Command -Name Group-Object         -Module Microsoft.PowerShell.Utility    @safeCommandLookupParameters
        'Import-LocalizedData' = Get-Command -Name Import-LocalizedData -Module Microsoft.PowerShell.Utility    @safeCommandLookupParameters
        'Import-Module'        = Get-Command -Name Import-Module        -Module Microsoft.PowerShell.Core       @safeCommandLookupParameters
        'Join-Path'            = Get-Command -Name Join-Path            -Module Microsoft.PowerShell.Management @safeCommandLookupParameters
        'Measure-Object'       = Get-Command -Name Measure-Object       -Module Microsoft.PowerShell.Utility    @safeCommandLookupParameters
        'New-Item'             = Get-Command -Name New-Item             -Module Microsoft.PowerShell.Management @safeCommandLookupParameters
        'New-ItemProperty'     = Get-Command -Name New-ItemProperty     -Module Microsoft.PowerShell.Management @safeCommandLookupParameters
        'New-Module'           = Get-Command -Name New-Module           -Module Microsoft.PowerShell.Core       @safeCommandLookupParameters
        'New-Object'           = Get-Command -Name New-Object           -Module Microsoft.PowerShell.Utility    @safeCommandLookupParameters
        'New-PSDrive'          = Get-Command -Name New-PSDrive          -Module Microsoft.PowerShell.Management @safeCommandLookupParameters
        'New-Variable'         = Get-Command -Name New-Variable         -Module Microsoft.PowerShell.Utility    @safeCommandLookupParameters
        'Out-Host'             = Get-Command -Name Out-Host             -Module $outHostModule                  @safeCommandLookupParameters
        'Out-File'             = Get-Command -Name Out-File             -Module Microsoft.PowerShell.Utility    @safeCommandLookupParameters
        'Out-Null'             = Get-Command -Name Out-Null             -Module $outNullModule                  @safeCommandLookupParameters
        'Out-String'           = Get-Command -Name Out-String           -Module Microsoft.PowerShell.Utility    @safeCommandLookupParameters
        'Pop-Location'         = Get-Command -Name Pop-Location         -Module Microsoft.PowerShell.Management @safeCommandLookupParameters
        'Push-Location'        = Get-Command -Name Push-Location        -Module Microsoft.PowerShell.Management @safeCommandLookupParameters
        'Remove-Item'          = Get-Command -Name Remove-Item          -Module Microsoft.PowerShell.Management @safeCommandLookupParameters
        'Remove-PSBreakpoint'  = Get-Command -Name Remove-PSBreakpoint  -Module Microsoft.PowerShell.Utility    @safeCommandLookupParameters
        'Remove-PSDrive'       = Get-Command -Name Remove-PSDrive       -Module Microsoft.PowerShell.Management @safeCommandLookupParameters
        'Remove-Variable'      = Get-Command -Name Remove-Variable      -Module Microsoft.PowerShell.Utility    @safeCommandLookupParameters
        'Resolve-Path'         = Get-Command -Name Resolve-Path         -Module Microsoft.PowerShell.Management @safeCommandLookupParameters
        'Select-Object'        = Get-Command -Name Select-Object        -Module Microsoft.PowerShell.Utility    @safeCommandLookupParameters
        'Set-Content'          = Get-Command -Name Set-Content          -Module Microsoft.PowerShell.Management @safeCommandLookupParameters
        'Set-Location'         = Get-Command -Name Set-Location         -Module Microsoft.PowerShell.Management @safeCommandLookupParameters
        'Set-PSBreakpoint'     = Get-Command -Name Set-PSBreakpoint     -Module Microsoft.PowerShell.Utility    @safeCommandLookupParameters
        'Set-StrictMode'       = Get-Command -Name Set-StrictMode       -Module Microsoft.PowerShell.Core       @safeCommandLookupParameters
        'Set-Variable'         = Get-Command -Name Set-Variable         -Module Microsoft.PowerShell.Utility    @safeCommandLookupParameters
        'Sort-Object'          = Get-Command -Name Sort-Object          -Module Microsoft.PowerShell.Utility    @safeCommandLookupParameters
        'Split-Path'           = Get-Command -Name Split-Path           -Module Microsoft.PowerShell.Management @safeCommandLookupParameters
        'Start-Sleep'          = Get-Command -Name Start-Sleep          -Module Microsoft.PowerShell.Utility    @safeCommandLookupParameters
        'Test-Path'            = Get-Command -Name Test-Path            -Module Microsoft.PowerShell.Management @safeCommandLookupParameters
        'Where-Object'         = Get-Command -Name Where-Object         -Module Microsoft.PowerShell.Core       @safeCommandLookupParameters
        'Write-Error'          = Get-Command -Name Write-Error          -Module Microsoft.PowerShell.Utility    @safeCommandLookupParameters
        'Write-Host'           = Get-Command -Name Write-Host           -Module Microsoft.PowerShell.Utility    @safeCommandLookupParameters
        'Write-Progress'       = Get-Command -Name Write-Progress       -Module Microsoft.PowerShell.Utility    @safeCommandLookupParameters
        'Write-Verbose'        = Get-Command -Name Write-Verbose        -Module Microsoft.PowerShell.Utility    @safeCommandLookupParameters
        'Write-Warning'        = Get-Command -Name Write-Warning        -Module Microsoft.PowerShell.Utility    @safeCommandLookupParameters
    }
    
    # Not all platforms have Get-WmiObject (Nano or PSCore 6.0.0-beta.x on Linux)
    # Get-CimInstance is preferred, but we can use Get-WmiObject if it exists
    # Moreover, it shouldn't really be fatal if neither of those cmdlets
    # exist
    if ( Get-Command -ea SilentlyContinue Get-CimInstance ) {
        $script:SafeCommands['Get-CimInstance'] = Get-Command -Name Get-CimInstance -Module CimCmdlets @safeCommandLookupParameters
    }
    elseif ( Get-command -ea SilentlyContinue Get-WmiObject ) {
        $script:SafeCommands['Get-WmiObject'] = Get-Command -Name Get-WmiObject   -Module Microsoft.PowerShell.Management @safeCommandLookupParameters
    }
    elseif ( Get-Command -ea SilentlyContinue uname -Type Application ) {
        $script:SafeCommands['uname'] = Get-Command -Name uname -Type Application | Select-Object -First 1
        if ( Get-Command -ea SilentlyContinue id -Type Application ) {
            $script:SafeCommands['id'] = Get-Command -Name id -Type Application | Select-Object -First 1
        }
    }
    else {
        Write-Warning "OS Information retrieval is not possible, reports will contain only partial system data"
    }
    
    # little sanity check to make sure we don't blow up a system with a typo up there
    # (not that I've EVER done that by, for example, mapping New-Item to Remove-Item...)
    
    foreach ($keyValuePair in $script:SafeCommands.GetEnumerator()) {
        if ($keyValuePair.Key -ne $keyValuePair.Value.Name) {
            throw "SafeCommands entry for $($keyValuePair.Key) does not hold a reference to the proper command."
        }
    }
    
    $script:AssertionOperators = & $SafeCommands['New-Object'] 'Collections.Generic.Dictionary[string,object]'([StringComparer]::InvariantCultureIgnoreCase)
    $script:AssertionAliases = & $SafeCommands['New-Object'] 'Collections.Generic.Dictionary[string,object]'([StringComparer]::InvariantCultureIgnoreCase)
    $script:AssertionDynamicParams = & $SafeCommands['New-Object'] System.Management.Automation.RuntimeDefinedParameterDictionary
    $script:DisableScopeHints = $true
    
    function Count-Scopes {
        param(
            [Parameter(Mandatory = $true)]
            $ScriptBlock)
    
        if ($script:DisableScopeHints) {
            return 0
        }
    
        # automatic variable that can help us count scopes must be constant a must not be all scopes
        # from the standard ones only Error seems to be that, let's ensure it is like that everywhere run
        # other candidate variables can be found by this code
        # Get-Variable  | where { -not ($_.Options -band [Management.Automation.ScopedItemOptions]"AllScope") -and $_.Options -band $_.Options -band [Management.Automation.ScopedItemOptions]"Constant" }
    
        # get-variable steps on it's toes and recurses when we mock it in a test
        # and we are also invoking this in user scope so we need to pass the reference
        # to the safely captured function in the user scope
        $safeGetVariable = $script:SafeCommands['Get-Variable']
        $sb = {
            param($safeGetVariable)
            $err = (& $safeGetVariable -Name Error).Options
            if ($err -band "AllScope" -or (-not ($err -band "Constant"))) {
                throw "Error variable is set to AllScope, or is not marked as constant cannot use it to count scopes on this platform."
            }
    
            $scope = 0
            while ($null -eq (& $safeGetVariable -Name Error -Scope $scope -ErrorAction SilentlyContinue)) {
                $scope++
            }
    
            $scope - 1 # because we are in a function
        }
    
        $flags = [System.Reflection.BindingFlags]'Instance,NonPublic'
        $property = [scriptblock].GetProperty('SessionStateInternal', $flags)
        $ssi = $property.GetValue($ScriptBlock, $null)
        $property.SetValue($sb, $ssi, $null)
    
        &$sb $safeGetVariable
    }
    
    function Write-ScriptBlockInvocationHint {
        param(
            [Parameter(Mandatory = $true)]
            [ScriptBlock] $ScriptBlock,
            [Parameter(Mandatory = $true)]
            [String]
            $Hint
        )
    
        if ($script:DisableScopeHints) {
            return
        }
    
        $scope = Get-ScriptBlockHint $ScriptBlock
        $count = Count-Scopes -ScriptBlock $ScriptBlock
    
        Write-Hint "Invoking scriptblock from location '$Hint' in state '$scope', $count scopes deep:
        {
            $ScriptBlock
        }`n`n"
    }
    
    function Write-Hint ($Hint) {
        if ($script:DisableScopeHints) {
            return
        }
    
        Write-Host -ForegroundColor Cyan $Hint
    }
    
    function Test-Hint {
        param (
            [Parameter(Mandatory = $true)]
            $InputObject
        )
    
        if ($script:DisableScopeHints) {
            return $true
        }
    
        $property = $InputObject | Get-Member -Name Hint -MemberType NoteProperty
        if ($null -eq $property) {
            return $false
        }
    
        Test-NullOrWhiteSpace $property.Value
    }
    
    function Set-Hint {
        param(
            [Parameter(Mandatory = $true)]
            [String] $Hint,
            [Parameter(Mandatory = $true)]
            $InputObject,
            [Switch] $Force
        )
    
        if ($script:DisableScopeHints) {
            return
        }
    
        if ($InputObject | Get-Member -Name Hint -MemberType NoteProperty) {
            $hintIsNotSet = Test-NullOrWhiteSpace $InputObject.Hint
            if ($Force -or $hintIsNotSet) {
                $InputObject.Hint = $Hint
            }
        }
        else {
            # do not change this to be called without the pipeline, it will throw: Cannot evaluate parameter 'InputObject' because its argument is specified as a script block and there is no input. A script block cannot be evaluated without input.
            $InputObject | Add-Member -Name Hint -Value $Hint -MemberType NoteProperty
        }
    }
    
    function Set-SessionStateHint {
        param(
            [Parameter(Mandatory = $true)]
            [String] $Hint,
            [Parameter(Mandatory = $true)]
            [Management.Automation.SessionState] $SessionState,
            [Switch] $PassThru
        )
    
        if ($script:DisableScopeHints) {
            if ($PassThru) {
                return $SessionState
            }
            return
        }
    
        # in all places where we capture SessionState we mark its internal state with a hint
        # the internal state does not change and we use it to invoke scriptblock in diferent
        # states, setting the hint on SessionState is only secondary to make is easier to debug
        $flags = [System.Reflection.BindingFlags]'Instance,NonPublic'
        $internalSessionState = $SessionState.GetType().GetProperty('Internal', $flags).GetValue($SessionState, $null)
        if ($null -eq $internalSessionState) {
            throw "SessionState does not have any internal SessionState, this should never happen."
        }
    
        $hashcode = $internalSessionState.GetHashCode()
        # optionally sets the hint if there was none, so the hint from the
        # function that first captured this session state is preserved
        Set-Hint -Hint "$Hint ($hashcode))" -InputObject $internalSessionState
        # the public session state should always depend on the internal state
        Set-Hint -Hint $internalSessionState.Hint -InputObject $SessionState -Force
    
        if ($PassThru) {
            $SessionState
        }
    }
    
    function Get-SessionStateHint {
        param(
            [Parameter(Mandatory = $true)]
            [Management.Automation.SessionState] $SessionState
        )
    
        if ($script:DisableScopeHints) {
            return
        }
    
        # the hint is also attached to the session state object, but sessionstate objects are recreated while
        # the internal state stays static so to see the hint on object that we receive via $PSCmdlet.SessionState we need
        # to look at the InternalSessionState. the internal state should be never null so just looking there is enough
        $flags = [System.Reflection.BindingFlags]'Instance,NonPublic'
        $internalSessionState = $SessionState.GetType().GetProperty('Internal', $flags).GetValue($SessionState, $null)
        if (Test-Hint $internalSessionState) {
            $internalSessionState.Hint
        }
    }
    
    function Set-ScriptBlockHint {
        param(
            [Parameter(Mandatory = $true)]
            [ScriptBlock] $ScriptBlock,
            [string] $Hint
        )
    
        if ($script:DisableScopeHints) {
            return
        }
    
        $flags = [System.Reflection.BindingFlags]'Instance,NonPublic'
        $internalSessionState = $ScriptBlock.GetType().GetProperty('SessionStateInternal', $flags).GetValue($ScriptBlock, $null)
        if ($null -eq $internalSessionState) {
            if (Test-Hint -InputObject $ScriptBlock) {
                # the scriptblock already has a hint and there is not internal state
                # so the hint on the scriptblock is enough
                # if there was an internal state we would try to copy the hint from it
                # onto the scriptblock to keep them in sync
                return
            }
    
            if ($null -eq $Hint) {
                throw "Cannot set ScriptBlock hint because it is unbound ScriptBlock (with null internal state) and no -Hint was provided."
            }
    
            # adds hint on the ScriptBlock
            # the internal session state is null so we must attach the hint directly
            # on the scriptblock
            Set-Hint -Hint "$Hint (Unbound)" -InputObject $ScriptBlock -Force
        }
        else {
            if (Test-Hint -InputObject $internalSessionState) {
                # there already is hint on the internal state, we take it and sync
                # it with the hint on the object
                Set-Hint -Hint $internalSessionState.Hint -InputObject $ScriptBlock -Force
                return
            }
    
            if ($null -eq $Hint) {
                throw "Cannot set ScriptBlock hint because it's internal state does not have any Hint and no external -Hint was provided."
            }
    
            $hashcode = $internalSessionState.GetHashCode()
            $Hint = "$Hint - ($hashCode)"
            Set-Hint -Hint $Hint -InputObject $internalSessionState -Force
            Set-Hint -Hint $Hint -InputObject $ScriptBlock -Force
        }
    }
    
    function Get-ScriptBlockHint {
        param(
            [Parameter(Mandatory = $true)]
            [ScriptBlock] $ScriptBlock
        )
    
        if ($script:DisableScopeHints) {
            return
        }
    
        # the hint is also attached to the scriptblock object, but not all scriptblocks are tagged by us,
        # the internal state stays static so to see the hint on object that we receive we need to look at the InternalSessionState
        $flags = [System.Reflection.BindingFlags]'Instance,NonPublic'
        $internalSessionState = $ScriptBlock.GetType().GetProperty('SessionStateInternal', $flags).GetValue($ScriptBlock, $null)
    
    
        if ($null -ne $internalSessionState -and (Test-Hint $internalSessionState)) {
            return $internalSessionState.Hint
        }
    
        if (Test-Hint $ScriptBlock) {
            return $ScriptBlock.Hint
        }
    
        "Unknown unbound ScriptBlock"
    }
    
    
    function Test-NullOrWhiteSpace {
        param ([string]$String)
    
        $String -match "^\s*$"
    }
    
    function Assert-ValidAssertionName {
        param([string]$Name)
        if ($Name -notmatch '^\S+$') {
            throw "Assertion name '$name' is invalid, assertion name must be a single word."
        }
    }
    
    function Assert-ValidAssertionAlias {
        param([string[]]$Alias)
        if ($Alias -notmatch '^\S+$') {
            throw "Assertion alias '$string' is invalid, assertion alias must be a single word."
        }
    }
    
    function Add-AssertionOperator {
        <#
    .SYNOPSIS
        Register an Assertion Operator with Pester
    .DESCRIPTION
        This function allows you to create custom Should assertions.
    .EXAMPLE
        function BeAwesome($ActualValue, [switch] $Negate)
        {
    
            [bool] $succeeded = $ActualValue -eq 'Awesome'
            if ($Negate) { $succeeded = -not $succeeded }
    
            if (-not $succeeded)
            {
                if ($Negate)
                {
                    $failureMessage = "{$ActualValue} is Awesome"
                }
                else
                {
                    $failureMessage = "{$ActualValue} is not Awesome"
                }
            }
    
            return New-Object psobject -Property @{
                Succeeded      = $succeeded
                FailureMessage = $failureMessage
            }
        }
    
        Add-AssertionOperator -Name  BeAwesome `
                            -Test  $function:BeAwesome `
                            -Alias 'BA'
    
        PS C:\> "bad" | should -BeAwesome
        {bad} is not Awesome
    .PARAMETER Name
        The name of the assertion. This will become a Named Parameter of Should.
    .PARAMETER Test
        The test function. The function must return a PSObject with a [Bool]succeeded and a [string]failureMessage property.
    .PARAMETER Alias
        A list of aliases for the Named Parameter.
    .PARAMETER SupportsArrayInput
        Does the test function support the passing an array of values to test.
    .PARAMETER InternalName
        If -Name is different from the actual function name, record the actual function name here.
        Used by Get-ShouldOperator to pull function help.
    #>
        [CmdletBinding()]
        param (
            [Parameter(Mandatory = $true)]
            [string] $Name,
    
            [Parameter(Mandatory = $true)]
            [scriptblock] $Test,
    
            [ValidateNotNullOrEmpty()]
            [AllowEmptyCollection()]
            [string[]] $Alias = @(),
    
            [Parameter()]
            [string] $InternalName,
    
            [switch] $SupportsArrayInput
        )
    
        $entry = New-Object psobject -Property @{
            Test               = $Test
            SupportsArrayInput = [bool]$SupportsArrayInput
            Name               = $Name
            Alias              = $Alias
            InternalName       = If ($InternalName) {
                $InternalName
            }
            Else {
                $Name
            }
        }
        if (Test-AssertionOperatorIsDuplicate -Operator $entry) {
            # This is an exact duplicate of an existing assertion operator.
            return
        }
    
        $namesToCheck = @(
            $Name
            $Alias
        )
    
        Assert-AssertionOperatorNameIsUnique -Name $namesToCheck
    
        $script:AssertionOperators[$Name] = $entry
    
        foreach ($string in $Alias | Where { -not (Test-NullOrWhiteSpace $_)}) {
            Assert-ValidAssertionAlias -Alias $string
            $script:AssertionAliases[$string] = $Name
        }
    
        Add-AssertionDynamicParameterSet -AssertionEntry $entry
    }
    
    function Test-AssertionOperatorIsDuplicate {
        param (
            [psobject] $Operator
        )
    
        $existing = $script:AssertionOperators[$Operator.Name]
        if (-not $existing) {
            return $false
        }
    
        return $Operator.SupportsArrayInput -eq $existing.SupportsArrayInput -and
        $Operator.Test.ToString() -eq $existing.Test.ToString() -and
        -not (Compare-Object $Operator.Alias $existing.Alias)
    }
    function Assert-AssertionOperatorNameIsUnique {
        param (
            [string[]] $Name
        )
    
        foreach ($string in $name | Where { -not (Test-NullOrWhiteSpace $_)}) {
            Assert-ValidAssertionName -Name $string
    
            if ($script:AssertionOperators.ContainsKey($string)) {
                throw "Assertion operator name '$string' has been added multiple times."
            }
    
            if ($script:AssertionAliases.ContainsKey($string)) {
                throw "Assertion operator name '$string' already exists as an alias for operator '$($script:AssertionAliases[$key])'"
            }
        }
    }
    
    function Add-AssertionDynamicParameterSet {
        param (
            [object] $AssertionEntry
        )
    
        ${function:__AssertionTest__} = $AssertionEntry.Test
        $commandInfo = Get-Command __AssertionTest__ -CommandType Function
        $metadata = [System.Management.Automation.CommandMetadata]$commandInfo
    
        $attribute = New-Object Management.Automation.ParameterAttribute
        $attribute.ParameterSetName = $AssertionEntry.Name
        $attribute.Mandatory = $true
    
        $attributeCollection = New-Object Collections.ObjectModel.Collection[Attribute]
        $null = $attributeCollection.Add($attribute)
        if (-not (Test-NullOrWhiteSpace $AssertionEntry.Alias)) {
            Assert-ValidAssertionAlias -Alias $AssertionEntry.Alias
            $attribute = New-Object System.Management.Automation.AliasAttribute($AssertionEntry.Alias)
            $attributeCollection.Add($attribute)
        }
    
        $dynamic = New-Object System.Management.Automation.RuntimeDefinedParameter($AssertionEntry.Name, [switch], $attributeCollection)
        $null = $script:AssertionDynamicParams.Add($AssertionEntry.Name, $dynamic)
    
        if ($script:AssertionDynamicParams.ContainsKey('Not')) {
            $dynamic = $script:AssertionDynamicParams['Not']
        }
        else {
            $dynamic = New-Object System.Management.Automation.RuntimeDefinedParameter('Not', [switch], (New-Object System.Collections.ObjectModel.Collection[Attribute]))
            $null = $script:AssertionDynamicParams.Add('Not', $dynamic)
        }
    
        $attribute = New-Object System.Management.Automation.ParameterAttribute
        $attribute.ParameterSetName = $AssertionEntry.Name
        $attribute.Mandatory = $false
        $null = $dynamic.Attributes.Add($attribute)
    
        $i = 1
        foreach ($parameter in $metadata.Parameters.Values) {
            # common parameters that are already defined
            if ($parameter.Name -eq 'ActualValue' -or $parameter.Name -eq 'Not' -or $parameter.Name -eq 'Negate') {
                continue
            }
    
    
            if ($script:AssertionOperators.ContainsKey($parameter.Name) -or $script:AssertionAliases.ContainsKey($parameter.Name)) {
                throw "Test block for assertion operator $($AssertionEntry.Name) contains a parameter named $($parameter.Name), which conflicts with another assertion operator's name or alias."
            }
    
            foreach ($alias in $parameter.Aliases) {
                if ($script:AssertionOperators.ContainsKey($alias) -or $script:AssertionAliases.ContainsKey($alias)) {
                    throw "Test block for assertion operator $($AssertionEntry.Name) contains a parameter named $($parameter.Name) with alias $alias, which conflicts with another assertion operator's name or alias."
                }
            }
    
            if ($script:AssertionDynamicParams.ContainsKey($parameter.Name)) {
                $dynamic = $script:AssertionDynamicParams[$parameter.Name]
            }
            else {
                # We deliberately use a type of [object] here to avoid conflicts between different assertion operators that may use the same parameter name.
                # We also don't bother to try to copy transformation / validation attributes here for the same reason.
                # Because we'll be passing these parameters on to the actual test function later, any errors will come out at that time.
    
                # few years later: using [object] causes problems with switch params (in my case -PassThru), because then we cannot use them without defining a value
                # so for switches we must prefer the conflicts over type
                if ([switch] -eq $parameter.ParameterType) {
                    $type = [switch]
                }
                else {
                    $type = [object]
                }
    
                $dynamic = New-Object System.Management.Automation.RuntimeDefinedParameter($parameter.Name, $type, (New-Object System.Collections.ObjectModel.Collection[Attribute]))
                $null = $script:AssertionDynamicParams.Add($parameter.Name, $dynamic)
            }
    
            $attribute = New-Object Management.Automation.ParameterAttribute
            $attribute.ParameterSetName = $AssertionEntry.Name
            $attribute.Mandatory = $false
            $attribute.Position = ($i++)
    
            $null = $dynamic.Attributes.Add($attribute)
        }
    }
    
    function Get-AssertionOperatorEntry([string] $Name) {
        return $script:AssertionOperators[$Name]
    }
    
    function Get-AssertionDynamicParams {
        return $script:AssertionDynamicParams
    }
    
    $Script:PesterRoot = & $SafeCommands['Split-Path'] -Path $MyInvocation.MyCommand.Path
    "$PesterRoot\Functions\*.ps1", "$PesterRoot\Functions\Assertions\*.ps1" |
        & $script:SafeCommands['Resolve-Path'] |
        & $script:SafeCommands['Where-Object'] { -not ($_.ProviderPath.ToLower().Contains(".tests.")) } |
        & $script:SafeCommands['ForEach-Object'] { . $_.ProviderPath }
    
    if (& $script:SafeCommands['Test-Path'] "$PesterRoot\Dependencies") {
        # sub-modules
        & $script:SafeCommands['Get-ChildItem'] "$PesterRoot\Dependencies\*\*.psm1" |
            & $script:SafeCommands['ForEach-Object'] { & $script:SafeCommands['Import-Module'] $_.FullName -Force -DisableNameChecking }
    }
    
    Add-Type -TypeDefinition @"
    using System;
    
    namespace Pester
    {
        [Flags]
        public enum OutputTypes
        {
            None = 0,
            Default = 1,
            Passed = 2,
            Failed = 4,
            Pending = 8,
            Skipped = 16,
            Inconclusive = 32,
            Describe = 64,
            Context = 128,
            Summary = 256,
            Header = 512,
            All = Default | Passed | Failed | Pending | Skipped | Inconclusive | Describe | Context | Summary | Header,
            Fails = Default | Failed | Pending | Skipped | Inconclusive | Describe | Context | Summary | Header
        }
    }
    "@
    
    function Has-Flag {
        param
        (
            [Parameter(Mandatory = $true)]
            [Pester.OutputTypes]
            $Setting,
            [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
            [Pester.OutputTypes]
            $Value
        )
    
        0 -ne ($Setting -band $Value)
    }
    
    function Invoke-Pester {
        <#
        .SYNOPSIS
        Runs Pester tests
    
        .DESCRIPTION
        The Invoke-Pester function runs Pester tests, including *.Tests.ps1 files and
        Pester tests in PowerShell scripts.
    
        You can run scripts that include Pester tests just as you would any other
        Windows PowerShell script, including typing the full path at the command line
        and running in a script editing program. Typically, you use Invoke-Pester to run
        all Pester tests in a directory, or to use its many helpful parameters,
        including parameters that generate custom objects or XML files.
    
        By default, Invoke-Pester runs all *.Tests.ps1 files in the current directory
        and all subdirectories recursively. You can use its parameters to select tests
        by file name, test name, or tag.
    
        To run Pester tests in scripts that take parameter values, use the Script
        parameter with a hash table value.
    
        Also, by default, Pester tests write test results to the console host, much like
        Write-Host does, but you can use the Show parameter set to None to suppress the host
        messages, use the PassThru parameter to generate a custom object
        (PSCustomObject) that contains the test results, use the OutputXml and
        OutputFormat parameters to write the test results to an XML file, and use the
        EnableExit parameter to return an exit code that contains the number of failed
        tests.
    
        You can also use the Strict parameter to fail all pending and skipped tests.
        This feature is ideal for build systems and other processes that require success
        on every test.
    
        To help with test design, Invoke-Pester includes a CodeCoverage parameter that
        lists commands, classes, functions, and lines of code that did not run during test
        execution and returns the code that ran as a percentage of all tested code.
    
        Invoke-Pester, and the Pester module that exports it, are products of an
        open-source project hosted on GitHub. To view, comment, or contribute to the
        repository, see https://github.com/Pester.
    
        .PARAMETER Script
        Specifies the test files that Pester runs. You can also use the Script parameter
        to pass parameter names and values to a script that contains Pester tests. The
        value of the Script parameter can be a string, a hash table, or a collection
        of hash tables and strings. Wildcard characters are supported.
    
        The Script parameter is optional. If you omit it, Invoke-Pester runs all
        *.Tests.ps1 files in the local directory and its subdirectories recursively.
    
        To run tests in other files, such as .ps1 files, enter the path and file name of
        the file. (The file name is required. Name patterns that end in "*.ps1" run only
        *.Tests.ps1 files.)
    
        To run a Pester test with parameter names and/or values, use a hash table as the
        value of the script parameter. The keys in the hash table are:
    
        -- Path [string] (required): Specifies a test to run. The value is a path\file
        name or name pattern. Wildcards are permitted. All hash tables in a Script
        parameter value must have a Path key.
    
        -- Parameters [hashtable]: Runs the script with the specified parameters. The
        value is a nested hash table with parameter name and value pairs, such as
        @{UserName = 'User01'; Id = '28'}.
    
        -- Arguments [array]: An array or comma-separated list of parameter values
        without names, such as 'User01', 28. Use this key to pass values to positional
        parameters.
    
    
        .PARAMETER TestName
        Runs only tests in Describe blocks that have the specified name or name pattern.
        Wildcard characters are supported.
    
        If you specify multiple TestName values, Invoke-Pester runs tests that have any
        of the values in the Describe name (it ORs the TestName values).
    
        .PARAMETER EnableExit
        Will cause Invoke-Pester to exit with a exit code equal to the number of failed
        tests once all tests have been run. Use this to "fail" a build when any tests fail.
    
        .PARAMETER OutputFile
        The path where Invoke-Pester will save formatted test results log file.
    
        The path must include the location and name of the folder and file name with
        the xml extension.
    
        If this path is not provided, no log will be generated.
    
        .PARAMETER OutputFormat
        The format of output. Two formats of output are supported: NUnitXML and
        LegacyNUnitXML.
    
        .PARAMETER Tag
        Runs only tests in Describe blocks with the specified Tag parameter values.
        Wildcard characters are supported. Tag values that include spaces or whitespace
        will be split into multiple tags on the whitespace.
    
        When you specify multiple Tag values, Invoke-Pester runs tests that have any
        of the listed tags (it ORs the tags). However, when you specify TestName
        and Tag values, Invoke-Pester runs only describe blocks that have one of the
        specified TestName values and one of the specified Tag values.
    
        If you use both Tag and ExcludeTag, ExcludeTag takes precedence.
    
        .PARAMETER ExcludeTag
        Omits tests in Describe blocks with the specified Tag parameter values. Wildcard
        characters are supported. Tag values that include spaces or whitespace
        will be split into multiple tags on the whitespace.
    
        When you specify multiple ExcludeTag values, Invoke-Pester omits tests that have
        any of the listed tags (it ORs the tags). However, when you specify TestName
        and ExcludeTag values, Invoke-Pester omits only describe blocks that have one
        of the specified TestName values and one of the specified Tag values.
    
        If you use both Tag and ExcludeTag, ExcludeTag takes precedence
    
        .PARAMETER PassThru
        Returns a custom object (PSCustomObject) that contains the test results.
    
        By default, Invoke-Pester writes to the host program, not to the output stream (stdout).
        If you try to save the result in a variable, the variable is empty unless you
        use the PassThru parameter.
    
        To suppress the host output, use the Show parameter set to None.
    
        .PARAMETER CodeCoverage
        Adds a code coverage report to the Pester tests. Takes strings or hash table values.
    
        A code coverage report lists the lines of code that did and did not run during
        a Pester test. This report does not tell whether code was tested; only whether
        the code ran during the test.
    
        By default, the code coverage report is written to the host program
        (like Write-Host). When you use the PassThru parameter, the custom object
        that Invoke-Pester returns has an additional CodeCoverage property that contains
        a custom object with detailed results of the code coverage test, including lines
        hit, lines missed, and helpful statistics.
    
        However, NUnitXML and LegacyNUnitXML output (OutputXML, OutputFormat) do not include
        any code coverage information, because it's not supported by the schema.
    
        Enter the path to the files of code under test (not the test file).
        Wildcard characters are supported. If you omit the path, the default is local
        directory, not the directory specified by the Script parameter. Pester test files
        are by default excluded from code coverage when a directory is provided. When you
        provide a test file directly using string, code coverage will be measured. To include
        tests in code coverage of a directory, use the dictionary syntax and provide
        IncludeTests = $true option, as shown below.
    
        To run a code coverage test only on selected classes, functions or lines in a script,
        enter a hash table value with the following keys:
    
        -- Path (P)(mandatory) <string>: Enter one path to the files. Wildcard characters
        are supported, but only one string is permitted.
        -- IncludeTests <bool>: Includes code coverage for Pester test files (*.tests.ps1).
        Default is false.
    
        One of the following: Class/Function or StartLine/EndLine
    
        -- Class (C) <string>: Enter the class name. Wildcard characters are
        supported, but only one string is permitted. Default is *.
        -- Function (F) <string>: Enter the function name. Wildcard characters are
        supported, but only one string is permitted. Default is *.
    
        -or-
    
        -- StartLine (S): Performs code coverage analysis beginning with the specified
        line. Default is line 1.
        -- EndLine (E): Performs code coverage analysis ending with the specified line.
        Default is the last line of the script.
    
        .PARAMETER CodeCoverageOutputFile
        The path where Invoke-Pester will save formatted code coverage results file.
    
        The path must include the location and name of the folder and file name with
        a required extension (usually the xml).
    
        If this path is not provided, no file will be generated.
    
        .PARAMETER CodeCoverageOutputFileFormat
        The name of a code coverage report file format.
    
        Default value is: JaCoCo.
    
        Currently supported formats are:
        - JaCoCo - this XML file format is compatible with the VSTS/TFS
    
        .PARAMETER Strict
        Makes Pending and Skipped tests to Failed tests. Useful for continuous
        integration where you need to make sure all tests passed.
    
        .PARAMETER Quiet
        The parameter Quiet is deprecated since Pester v. 4.0 and will be deleted
        in the next major version of Pester. Please use the parameter Show
        with value 'None' instead.
    
        The parameter Quiet suppresses the output that Pester writes to the host program,
        including the result summary and CodeCoverage output.
    
        This parameter does not affect the PassThru custom object or the XML output that
        is written when you use the Output parameters.
    
        .PARAMETER Show
        Customizes the output Pester writes to the screen. Available options are None, Default,
        Passed, Failed, Pending, Skipped, Inconclusive, Describe, Context, Summary, Header, All, Fails.
    
        The options can be combined to define presets.
        Common use cases are:
    
        None - to write no output to the screen.
        All - to write all available information (this is default option).
        Fails - to write everything except Passed (but including Describes etc.).
    
        A common setting is also Failed, Summary, to write only failed tests and test summary.
    
        This parameter does not affect the PassThru custom object or the XML output that
        is written when you use the Output parameters.
    
        .PARAMETER PesterOption
        Sets advanced options for the test execution. Enter a PesterOption object,
        such as one that you create by using the New-PesterOption cmdlet, or a hash table
        in which the keys are option names and the values are option values.
        For more information on the options available, see the help for New-PesterOption.
    
        .Example
        Invoke-Pester
    
        This command runs all *.Tests.ps1 files in the current directory and its subdirectories.
    
        .Example
        Invoke-Pester -Script .\Util*
    
        This commands runs all *.Tests.ps1 files in subdirectories with names that begin
        with 'Util' and their subdirectories.
    
        .Example
        Invoke-Pester -Script D:\MyModule, @{ Path = '.\Tests\Utility\ModuleUnit.Tests.ps1'; Parameters = @{ Name = 'User01' }; Arguments = srvNano16  }
    
        This command runs all *.Tests.ps1 files in D:\MyModule and its subdirectories.
        It also runs the tests in the ModuleUnit.Tests.ps1 file using the following
        parameters: .\Tests\Utility\ModuleUnit.Tests.ps1 srvNano16 -Name User01
    
        .Example
        Invoke-Pester -Script @{Script = $scriptText}
        This command runs all tests passed as string in $scriptText variable with no aditional parameters and arguments. This notation can be combined with
        Invoke-Pester -Script D:\MyModule, @{ Path = '.\Tests\Utility\ModuleUnit.Tests.ps1'; Parameters = @{ Name = 'User01' }; Arguments = srvNano16  }
        if needed. This command can be used when tests and scripts are stored not on the FileSystem, but somewhere else, and it is impossible to provide a path to it.
    
        .Example
        Invoke-Pester -TestName "Add Numbers"
    
        This command runs only the tests in the Describe block named "Add Numbers".
    
        .EXAMPLE
        $results = Invoke-Pester -Script D:\MyModule -PassThru -Show None
        $failed = $results.TestResult | where Result -eq 'Failed'
    
        $failed.Name
        cannot find help for parameter: Force : in Compress-Archive
        help for Force parameter in Compress-Archive has wrong Mandatory value
        help for Compress-Archive has wrong parameter type for Force
        help for Update parameter in Compress-Archive has wrong Mandatory value
        help for DestinationPath parameter in Expand-Archive has wrong Mandatory value
    
        $failed[0]
        Describe               : Test help for Compress-Archive in Microsoft.PowerShell.Archive (1.0.0.0)
        Context                : Test parameter help for Compress-Archive
        Name                   : cannot find help for parameter: Force : in Compress-Archive
        Result                 : Failed
        Passed                 : False
        Time                   : 00:00:00.0193083
        FailureMessage         : Expected: value to not be empty
        StackTrace             : at line: 279 in C:\GitHub\PesterTdd\Module.Help.Tests.ps1
                                279:                     $parameterHelp.Description.Text | Should Not BeNullOrEmpty
        ErrorRecord            : Expected: value to not be empty
        ParameterizedSuiteName :
        Parameters             : {}
    
        This examples uses the PassThru parameter to return a custom object with the
        Pester test results. By default, Invoke-Pester writes to the host program, but not
        to the output stream. It also uses the Show parameter set to None to suppress the host output.
    
        The first command runs Invoke-Pester with the PassThru and Show parameters and
        saves the PassThru output in the $results variable.
    
        The second command gets only failing results and saves them in the $failed variable.
    
        The third command gets the names of the failing results. The result name is the
        name of the It block that contains the test.
    
        The fourth command uses an array index to get the first failing result. The
        property values describe the test, the expected result, the actual result, and
        useful values, including a stack trace.
    
        .Example
        Invoke-Pester -EnableExit -OutputFile ".\artifacts\TestResults.xml" -OutputFormat NUnitXml
    
        This command runs all tests in the current directory and its subdirectories. It
        writes the results to the TestResults.xml file using the NUnitXml schema. The
        test returns an exit code equal to the number of test failures.
    
        .EXAMPLE
        Invoke-Pester -CodeCoverage 'ScriptUnderTest.ps1'
    
        Runs all *.Tests.ps1 scripts in the current directory, and generates a coverage
        report for all commands in the "ScriptUnderTest.ps1" file.
    
        .EXAMPLE
        Invoke-Pester -CodeCoverage @{ Path = 'ScriptUnderTest.ps1'; Function = 'FunctionUnderTest' }
    
        Runs all *.Tests.ps1 scripts in the current directory, and generates a coverage
        report for all commands in the "FunctionUnderTest" function in the "ScriptUnderTest.ps1" file.
    
        .EXAMPLE
        Invoke-Pester -CodeCoverage 'ScriptUnderTest.ps1' -CodeCoverageOutputFile '.\artifacts\TestOutput.xml'
    
        Runs all *.Tests.ps1 scripts in the current directory, and generates a coverage
        report for all commands in the "ScriptUnderTest.ps1" file, and writes the coverage report to TestOutput.xml
        file using the JaCoCo XML Report DTD.
    
        .EXAMPLE
        Invoke-Pester -CodeCoverage @{ Path = 'ScriptUnderTest.ps1'; StartLine = 10; EndLine = 20 }
    
        Runs all *.Tests.ps1 scripts in the current directory, and generates a coverage
        report for all commands on lines 10 through 20 in the "ScriptUnderTest.ps1" file.
    
        .EXAMPLE
        Invoke-Pester -Script C:\Tests -Tag UnitTest, Newest -ExcludeTag Bug
    
        This command runs *.Tests.ps1 files in C:\Tests and its subdirectories. In those
        files, it runs only tests that have UnitTest or Newest tags, unless the test
        also has a Bug tag.
    
        .LINK
        https://github.com/pester/Pester/wiki/Invoke-Pester
    
        .LINK
        Describe
        about_Pester
        New-PesterOption
    
        #>
        [CmdletBinding(DefaultParameterSetName = 'Default')]
        param(
            [Parameter(Position = 0, Mandatory = 0)]
            [Alias('Path', 'relative_path')]
            [object[]]$Script = '.',
    
            [Parameter(Position = 1, Mandatory = 0)]
            [Alias("Name")]
            [string[]]$TestName,
    
            [Parameter(Position = 2, Mandatory = 0)]
            [switch]$EnableExit,
    
            [Parameter(Position = 4, Mandatory = 0)]
            [Alias('Tags')]
            [string[]]$Tag,
    
            [string[]]$ExcludeTag,
    
            [switch]$PassThru,
    
            [object[]] $CodeCoverage = @(),
    
            [string] $CodeCoverageOutputFile,
    
            [ValidateSet('JaCoCo')]
            [String]$CodeCoverageOutputFileFormat = "JaCoCo",
    
            [Switch]$Strict,
    
            [Parameter(Mandatory = $true, ParameterSetName = 'NewOutputSet')]
            [string] $OutputFile,
    
            [Parameter(ParameterSetName = 'NewOutputSet')]
            [ValidateSet('NUnitXml')]
            [string] $OutputFormat = 'NUnitXml',
    
            [Switch]$Quiet,
    
            [object]$PesterOption,
    
            [Pester.OutputTypes]$Show = 'All'
        )
        begin {
            # Ensure when running Pester that we're using RSpec strings
            & $script:SafeCommands['Import-LocalizedData'] -BindingVariable Script:ReportStrings -BaseDirectory $PesterRoot -FileName RSpec.psd1 -ErrorAction SilentlyContinue
    
            # Fallback to en-US culture strings
            If ([String]::IsNullOrEmpty($ReportStrings)) {
    
                & $script:SafeCommands['Import-LocalizedData'] -BaseDirectory $PesterRoot -BindingVariable Script:ReportStrings -UICulture 'en-US' -FileName RSpec.psd1 -ErrorAction Stop
    
            }
        }
    
        end {
            if ($PSBoundParameters.ContainsKey('Quiet')) {
                & $script:SafeCommands['Write-Warning'] 'The -Quiet parameter has been deprecated; please use the new -Show parameter instead. To get no output use -Show None.'
                & $script:SafeCommands['Start-Sleep'] -Seconds 2
    
                if (!$PSBoundParameters.ContainsKey('Show')) {
                    $Show = [Pester.OutputTypes]::None
                }
            }
    
            $script:mockTable = @{}
            Remove-MockFunctionsAndAliases
            $sessionState = Set-SessionStateHint -PassThru  -Hint "Caller - Captured in Invoke-Pester" -SessionState $PSCmdlet.SessionState
            $pester = New-PesterState -TestNameFilter $TestName -TagFilter $Tag -ExcludeTagFilter $ExcludeTag -SessionState $SessionState -Strict:$Strict -Show:$Show -PesterOption $PesterOption -RunningViaInvokePester
    
            try {
                Enter-CoverageAnalysis -CodeCoverage $CodeCoverage -PesterState $pester
                Write-PesterStart $pester $Script
    
                $invokeTestScript = {
                    param (
                        [Parameter(Position = 0)]
                        [string] $Path,
                        [string] $Script,
                        [object[]] $Arguments = @(),
                        [System.Collections.IDictionary] $Parameters = @{}
                    )
    
                    if (-not [string]::IsNullOrEmpty($Path)) {
                        & $Path @Parameters @Arguments
                    }
                    elseif (-not [string]::IsNullOrEmpty($Script)) {
                        $scriptBlock = [scriptblock]::Create($Script)
                        Set-ScriptBlockHint -Hint "Unbound ScriptBlock from Invoke-Pester" -ScriptBlock $scriptBlock
                        Invoke-Command -ScriptBlock ($scriptBlock)
                    }
                }
    
                Set-ScriptBlockScope -ScriptBlock $invokeTestScript -SessionState $sessionState
                $testScripts = @(ResolveTestScripts $Script)
    
    
                foreach ($testScript in $testScripts) {
                    #Get test description for better output
                    if (-not [string]::IsNullOrEmpty($testScript.Path)) {
                        $testDescription = $testScript.Path
                    }
                    elseif (-not [string]::IsNullOrEmpty($testScript.Script)) {
                        $testDescription = $testScript.Script
                    }
    
                    try {
                        $pester.EnterTestGroup($testDescription, 'Script')
                        Write-Describe $testDescription -CommandUsed Script
                        do {
                            $testOutput = & $invokeTestScript -Path $testScript.Path -Script $testScript.Script -Arguments $testScript.Arguments -Parameters $testScript.Parameters
                        } until ($true)
                    }
                    catch {
                        $firstStackTraceLine = $null
                        if (($_ | & $SafeCommands['Get-Member'] -Name ScriptStackTrace) -and $null -ne $_.ScriptStackTrace) {
                            $firstStackTraceLine = $_.ScriptStackTrace -split '\r?\n' | & $script:SafeCommands['Select-Object'] -First 1
                        }
                        $pester.AddTestResult("Error occurred in test script '$($testDescription)'", "Failed", $null, $_.Exception.Message, $firstStackTraceLine, $null, $null, $_)
    
                        # This is a hack to ensure that XML output is valid for now.  The test-suite names come from the Describe attribute of the TestResult
                        # objects, and a blank name is invalid NUnit XML.  This will go away when we promote test scripts to have their own test-suite nodes,
                        # planned for v4.0
                        $pester.TestResult[-1].Describe = "Error in $($testDescription)"
    
                        $pester.TestResult[-1] | Write-PesterResult
                    }
                    finally {
                        Exit-MockScope
                        $pester.LeaveTestGroup($testDescription, 'Script')
                    }
                }
    
                $pester | Write-PesterReport
                $coverageReport = Get-CoverageReport -PesterState $pester
                Write-CoverageReport -CoverageReport $coverageReport
                if ((& $script:SafeCommands['Get-Variable'] -Name CodeCoverageOutputFile -ValueOnly -ErrorAction $script:IgnoreErrorPreference) `
                        -and (& $script:SafeCommands['Get-Variable'] -Name CodeCoverageOutputFileFormat -ValueOnly -ErrorAction $script:IgnoreErrorPreference) -eq 'JaCoCo') {
                    $jaCoCoReport = Get-JaCoCoReportXml -PesterState $pester -CoverageReport $coverageReport
                    $jaCoCoReport | & $SafeCommands['Out-File'] $CodeCoverageOutputFile -Encoding utf8
                }
                Exit-CoverageAnalysis -PesterState $pester
            }
            finally {
                Exit-MockScope
            }
    
            Set-PesterStatistics
    
            if (& $script:SafeCommands['Get-Variable'] -Name OutputFile -ValueOnly -ErrorAction $script:IgnoreErrorPreference) {
                Export-PesterResults -PesterState $pester -Path $OutputFile -Format $OutputFormat
            }
    
            if ($PassThru) {
                # Remove all runtime properties like current* and Scope
                $properties = @(
                    "TagFilter", "ExcludeTagFilter", "TestNameFilter", "ScriptBlockFilter", "TotalCount", "PassedCount", "FailedCount", "SkippedCount", "PendingCount", 'InconclusiveCount', "Time", "TestResult"
    
                    if ($CodeCoverage) {
                        @{ Name = 'CodeCoverage'; Expression = { $coverageReport } }
                    }
                )
    
                $pester | & $script:SafeCommands['Select-Object'] -Property $properties
            }
    
            if ($EnableExit) {
                Exit-WithCode -FailedCount $pester.FailedCount
            }
        }
    }
    
    function New-PesterOption {
        <#
        .SYNOPSIS
        Creates an object that contains advanced options for Invoke-Pester
        .DESCRIPTION
        By using New-PesterOption you can set options what allow easier integration with external applications or
        modifies output generated by Invoke-Pester.
        The result of New-PesterOption need to be assigned to the parameter 'PesterOption' of the Invoke-Pester function.
        .PARAMETER IncludeVSCodeMarker
        When this switch is set, an extra line of output will be written to the console for test failures, making it easier
        for VSCode's parser to provide highlighting / tooltips on the line where the error occurred.
        .PARAMETER TestSuiteName
        When generating NUnit XML output, this controls the name assigned to the root "test-suite" element.  Defaults to "Pester".
        .PARAMETER ScriptBlockFilter
        Filters scriptblock based on the path and line number. This is intended for integration with external tools so we don't rely on names (strings) that can have expandable variables in them.
        .PARAMETER Experimental
        Enables experimental features of Pester to be enabled.
        .PARAMETER ShowScopeHints
        EXPERIMENTAL: Enables debugging output for debugging tranisition among scopes. (Experimental flag needs to be used to enable this.)
    
        .INPUTS
        None
        You cannot pipe input to this command.
        .OUTPUTS
        System.Management.Automation.PSObject
        .EXAMPLE
            PS > $Options = New-PesterOption -TestSuiteName "Tests - Set A"
    
            PS > Invoke-Pester -PesterOption $Options -Outputfile ".\Results-Set-A.xml" -OutputFormat NUnitXML
    
            The result of commands will be execution of tests and saving results of them in a NUnitMXL file where the root "test-suite"
            will be named "Tests - Set A".
        .LINK
        https://github.com/pester/Pester/wiki/New-PesterOption
    
        .LINK
        Invoke-Pester
        #>
    
        [CmdletBinding()]
        param (
            [switch] $IncludeVSCodeMarker,
    
            [ValidateNotNullOrEmpty()]
            [string] $TestSuiteName = 'Pester',
    
            [switch] $Experimental,
    
            [switch] $ShowScopeHints,
    
            [hashtable[]] $ScriptBlockFilter
        )
    
        # in PowerShell 2 Add-Member can attach properties only to
        # PSObjects, I could work around this by capturing all instances
        # in checking them during runtime, but that would bring a lot of
        # object management problems - so let's just not allow this in PowerShell 2
        if ($Experimental -and $ShowScopeHints) {
            if ($PSVersionTable.PSVersion.Major -lt 3) {
                throw "Scope hints cannot be used on PowerShell 2 due to limitations of Add-Member."
            }
    
            $script:DisableScopeHints = $false
        }
        else {
            $script:DisableScopeHints = $true
        }
    
        return & $script:SafeCommands['New-Object'] psobject -Property @{
            IncludeVSCodeMarker = [bool] $IncludeVSCodeMarker
            TestSuiteName       = $TestSuiteName
            ShowScopeHints      = $ShowScopeHints
            Experimental        = $Experimental
            ScriptBlockFilter   = $ScriptBlockFilter
        }
    }
    
    function ResolveTestScripts {
        param ([object[]] $Path)
    
        $resolvedScriptInfo = @(
            foreach ($object in $Path) {
                if ($object -is [System.Collections.IDictionary]) {
                    $unresolvedPath = Get-DictionaryValueFromFirstKeyFound -Dictionary $object -Key 'Path', 'p'
                    $script = Get-DictionaryValueFromFirstKeyFound -Dictionary $object -Key 'Script'
                    $arguments = @(Get-DictionaryValueFromFirstKeyFound -Dictionary $object -Key 'Arguments', 'args', 'a')
                    $parameters = Get-DictionaryValueFromFirstKeyFound -Dictionary $object -Key 'Parameters', 'params'
    
                    if ($null -eq $Parameters) {
                        $Parameters = @{}
                    }
    
                    if ($unresolvedPath -isnot [string] -or $unresolvedPath -notmatch '\S' -and ($script -isnot [string] -or $script -notmatch '\S')) {
                        throw 'When passing hashtables to the -Path parameter, the Path key is mandatory, and must contain a single string.'
                    }
    
                    if ($null -ne $parameters -and $parameters -isnot [System.Collections.IDictionary]) {
                        throw 'When passing hashtables to the -Path parameter, the Parameters key (if present) must be assigned an IDictionary object.'
                    }
                }
                else {
                    $unresolvedPath = [string] $object
                    $script = [string] $object
                    $arguments = @()
                    $parameters = @{}
                }
    
                if (-not [string]::IsNullOrEmpty($unresolvedPath)) {
                    if ($unresolvedPath -notmatch '[\*\?\[\]]' -and
                        (& $script:SafeCommands['Test-Path'] -LiteralPath $unresolvedPath -PathType Leaf) -and
                        (& $script:SafeCommands['Get-Item'] -LiteralPath $unresolvedPath) -is [System.IO.FileInfo]) {
                        $extension = [System.IO.Path]::GetExtension($unresolvedPath)
                        if ($extension -ne '.ps1') {
                            & $script:SafeCommands['Write-Error'] "Script path '$unresolvedPath' is not a ps1 file."
                        }
                        else {
                            & $script:SafeCommands['New-Object'] psobject -Property @{
                                Path       = $unresolvedPath
                                Script     = $null
                                Arguments  = $arguments
                                Parameters = $parameters
                            }
                        }
                    }
                    else {
                        # World's longest pipeline?
    
                        & $script:SafeCommands['Resolve-Path'] -Path $unresolvedPath |
                            & $script:SafeCommands['Where-Object'] { $_.Provider.Name -eq 'FileSystem' } |
                            & $script:SafeCommands['Select-Object'] -ExpandProperty ProviderPath |
                            & $script:SafeCommands['Get-ChildItem'] -Include *.Tests.ps1 -Recurse |
                            & $script:SafeCommands['Where-Object'] { -not $_.PSIsContainer } |
                            & $script:SafeCommands['Select-Object'] -ExpandProperty FullName -Unique |
                            & $script:SafeCommands['ForEach-Object'] {
                            & $script:SafeCommands['New-Object'] psobject -Property @{
                                Path       = $_
                                Script     = $null
                                Arguments  = $arguments
                                Parameters = $parameters
                            }
                        }
                    }
                }
                elseif (-not [string]::IsNullOrEmpty($script)) {
                    & $script:SafeCommands['New-Object'] psobject -Property @{
                        Path       = $null
                        Script     = $script
                        Arguments  = $arguments
                        Parameters = $parameters
                    }
                }
            }
        )
    
        # Here, we have the option of trying to weed out duplicate file paths that also contain identical
        # Parameters / Arguments.  However, we already make sure that each object in $Path didn't produce
        # any duplicate file paths, and if the caller happens to pass in a set of parameters that produce
        # dupes, maybe that's not our problem.  For now, just return what we found.
    
        $resolvedScriptInfo
    }
    
    function Get-DictionaryValueFromFirstKeyFound {
        param ([System.Collections.IDictionary] $Dictionary, [object[]] $Key)
    
        foreach ($keyToTry in $Key) {
            if ($Dictionary.Contains($keyToTry)) {
                return $Dictionary[$keyToTry]
            }
        }
    }
    
    function Set-ScriptBlockScope {
        [CmdletBinding()]
        param (
            [Parameter(Mandatory = $true)]
            [scriptblock]
            $ScriptBlock,
    
            [Parameter(Mandatory = $true, ParameterSetName = 'FromSessionState')]
            [System.Management.Automation.SessionState]
            $SessionState,
    
            [Parameter(Mandatory = $true, ParameterSetName = 'FromSessionStateInternal')]
            [AllowNull()]
            $SessionStateInternal
        )
    
        $flags = [System.Reflection.BindingFlags]'Instance,NonPublic'
    
        if ($PSCmdlet.ParameterSetName -eq 'FromSessionState') {
            $SessionStateInternal = $SessionState.GetType().GetProperty('Internal', $flags).GetValue($SessionState, $null)
        }
    
        $property = [scriptblock].GetProperty('SessionStateInternal', $flags)
        $scriptBlockSessionState = $property.GetValue($ScriptBlock, $null)
    
        if (-not $script:DisableScopeHints) {
            # hint can be attached on the internal state (preferable) when the state is there.
            # if we are given unbound scriptblock with null internal state then we hope that
            # the source cmdlet set the hint directly on the ScriptBlock,
            # otherwise the origin is unknown and the cmdlet that allowed this scriptblock in
            # should be found and add hint
    
            $hint = $scriptBlockSessionState.Hint
            if ($null -eq $hint) {
                if ($null -ne $ScriptBlock.Hint) {
                    $hint = $ScriptBlock.Hint
                }
                else {
                    $hint = 'Unknown unbound ScriptBlock'
                }
            }
            Write-Hint "Setting ScriptBlock state from source state '$hint' to '$($SessionStateInternal.Hint)'"
        }
    
        $property.SetValue($ScriptBlock, $SessionStateInternal, $null)
    
        if (-not $script:DisableScopeHints) {
            Set-ScriptBlockHint -ScriptBlock $ScriptBlock
        }
    }
    
    function Get-ScriptBlockScope {
        [CmdletBinding()]
        param (
            [Parameter(Mandatory = $true)]
            [scriptblock]
            $ScriptBlock
        )
    
    
        $flags = [System.Reflection.BindingFlags]'Instance,NonPublic'
        $sessionStateInternal = [scriptblock].GetProperty('SessionStateInternal', $flags).GetValue($ScriptBlock, $null)
        if (-not $script:DisableScopeHints) {
            Write-Hint "Getting scope from ScriptBlock '$($sessionStateInternal.Hint)'"
        }
        $sessionStateInternal
    }
    
    function SafeGetCommand {
        <#
        .SYNOPSIS
        This command is used by Pester's Mocking framework.  You do not need to call it directly.
        #>
    
        return $script:SafeCommands['Get-Command']
    }
    
    function Set-PesterStatistics($Node) {
        if ($null -eq $Node) {
            $Node = $pester.TestActions
        }
    
        foreach ($action in $Node.Actions) {
            if ($action.Type -eq 'TestGroup') {
                Set-PesterStatistics -Node $action
    
                $Node.TotalCount += $action.TotalCount
                $Node.PassedCount += $action.PassedCount
                $Node.FailedCount += $action.FailedCount
                $Node.SkippedCount += $action.SkippedCount
                $Node.PendingCount += $action.PendingCount
                $Node.InconclusiveCount += $action.InconclusiveCount
            }
            elseif ($action.Type -eq 'TestCase') {
                $node.TotalCount++
    
                switch ($action.Result) {
                    Passed {
                        $Node.PassedCount++; break;
                    }
                    Failed {
                        $Node.FailedCount++; break;
                    }
                    Skipped {
                        $Node.SkippedCount++; break;
                    }
                    Pending {
                        $Node.PendingCount++; break;
                    }
                    Inconclusive {
                        $Node.InconclusiveCount++; break;
                    }
                }
            }
        }
    }
    
    function Contain-AnyStringLike ($Filter, $Collection) {
        foreach ($item in $Collection) {
            foreach ($value in $Filter) {
                if ($item -like $value) {
                    return $true
                }
            }
        }
        return $false
    }
    
    $snippetsDirectoryPath = "$PSScriptRoot\Snippets"
    if ((& $script:SafeCommands['Test-Path'] -Path Variable:\psise) -and
        ($null -ne $psISE) -and
        ($PSVersionTable.PSVersion.Major -ge 3) -and
        (& $script:SafeCommands['Test-Path'] $snippetsDirectoryPath)) {
        Import-IseSnippet -Path $snippetsDirectoryPath
    }
    
    function Assert-VerifiableMocks {
        <#
        .SYNOPSIS
        The function is for backward compatibility only. Please update your code and use 'Assert-VerifiableMock' instead.
    
        .DESCRIPTION
        The function was reintroduced in the version 4.0.8 of Pester to avoid loading older version of Pester when Assert-VerifiableMocks is called.
    
        The function will be removed finally in the next major version of Pester.
    
        .LINK
        https://github.com/pester/Pester/wiki/Migrating-from-Pester-3-to-Pester-4
    
        .LINK
        https://github.com/pester/Pester/issues/880
    
        #>
    
        [CmdletBinding()]
        param()
    
        Throw "This command has been renamed to 'Assert-VerifiableMock' (without the 's' at the end), please update your code. For more information see: https://github.com/pester/Pester/wiki/Migrating-from-Pester-3-to-Pester-4"
    
    }
    
    Set-SessionStateHint -Hint Pester -SessionState $ExecutionContext.SessionState
    # in the future rename the function to Add-ShouldOperator
    Set-Alias -Name Add-ShouldOperator -Value Add-AssertionOperator
    
    & $script:SafeCommands['Export-ModuleMember'] Describe, Context, It, In, Mock, Assert-VerifiableMock, Assert-VerifiableMocks, Assert-MockCalled, Set-TestInconclusive, Set-ItResult
    & $script:SafeCommands['Export-ModuleMember'] New-Fixture, Get-TestDriveItem, Should, Invoke-Pester, Setup, InModuleScope, Invoke-Mock
    & $script:SafeCommands['Export-ModuleMember'] BeforeEach, AfterEach, BeforeAll, AfterAll
    & $script:SafeCommands['Export-ModuleMember'] Get-MockDynamicParameter, Set-DynamicParameterVariable
    & $script:SafeCommands['Export-ModuleMember'] SafeGetCommand, New-PesterOption
    & $script:SafeCommands['Export-ModuleMember'] Invoke-Gherkin, Find-GherkinStep, BeforeEachFeature, BeforeEachScenario, AfterEachFeature, AfterEachScenario, GherkinStep -Alias Given, When, Then, And, But
    & $script:SafeCommands['Export-ModuleMember'] New-MockObject, Add-AssertionOperator, Get-ShouldOperator  -Alias Add-ShouldOperator
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUiib6z0gEo//d4bbI5ixcEGGY
    # c72ggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # 95+BHaZoxg7pHgl8U7Cylab6YlUwDQYJKoZIhvcNAQEBBQAEggEAoI+9MMrvbzOf
    # 2lH7fpNebfcSKsDyhm2FUJJiCVnlEe8umuJIEoprKRinWx3wkOYD8oJewh8zJj/u
    # VClzAkVdxd9FHfjDom1J/7PnYhsKZq9iguc+TffK4uU3wpjGsAL2g2oJ9yWJVs2E
    # RJc0v1oJO4yNGRKsYnkWhSbd6jOzciCtkUpI1Lk9e6xbpCBKhHju0/f+3A+NiTvc
    # /vENmvkmJVDfjrJErj1hqok3wbUoQp/2hgLmo6kNDe2+xvqldBRCDDAh+9nE11bf
    # /gs36nwDjKmIhbrNfUjqlW9/2Qft4CRsgkXQeQWm/0QLstRZ9aBDp6mRgfnYAtaT
    # WH38R8M9T6GCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzE5WjAjBgkqhkiG9w0BCQQx
    # FgQUAH1orhtOSbkqMzHIdKywHD8NExUwDQYJKoZIhvcNAQEBBQAEggEAhtdzs4Iu
    # OYDzRoiJ/cfYQ0RC5rAxXQb4rBOc/D7jLXPZmr6zCYsrTM5F/C+dtt+dYv4GltOO
    # uYj0xjFdKNI4bxTydasnoB2yCzRuah4ERAHG90kuwamkf2/OpHxaOaQwXWd2Ywkk
    # PnWUdWrTU6+QxCvqp6ST67gDRuJnHcUha4UTAa+mbf5F7fXjLFJHgOBSK5hjB4qf
    # dLa7Vo7nklAs7omRRzT+DU5Xy3HIjZTVIX0mbDLfUHSg1lmZtU0kJctqHj576BxX
    # ELuRMhGPhMEaO4HEZZiFe8f36QYMaStJTUVqdcxtyP7qLbHwiFi7u8jPYwWal0T0
    # kg/X4MMEoSid+Q==
    # SIG # End signature block
    
  • tools\Snippets\Context.snippets.ps1xml
  • tools\Snippets\Describe.snippets.ps1xml
  • tools\Snippets\It.snippets.ps1xml
  • tools\Snippets\ShouldBe.snippets.ps1xml
  • tools\Snippets\ShouldBeGreaterThan.snippets.ps1xml
  • tools\Snippets\ShouldBeLessThan.snippets.ps1xml
  • tools\Snippets\ShouldBeNullOrEmpty.snippets.ps1xml
  • tools\Snippets\ShouldExist.snippets.ps1xml
  • tools\Snippets\ShouldFileContentMatch.snippets.ps1xml
  • tools\Snippets\ShouldMatch.snippets.ps1xml
  • tools\Snippets\ShouldNotBe.snippets.ps1xml
  • tools\Functions\Assertions\Be.ps1 Show
    #Be
    function Should-Be ($ActualValue, $ExpectedValue, [switch] $Negate, [string] $Because) {
        <#
    .SYNOPSIS
    Compares one object with another for equality
    and throws if the two objects are not the same.
    
    .EXAMPLE
    $actual = "Actual value"
    PS C:\>$actual | Should -Be "actual value"
    
    This test will pass. -Be is not case sensitive.
    For a case sensitive assertion, see -BeExactly.
    
    .EXAMPLE
    $actual = "Actual value"
    PS C:\>$actual | Should -Be "not actual value"
    
    This test will fail, as the two strings are not identical.
    #>
        [bool] $succeeded = ArraysAreEqual $ActualValue $ExpectedValue
    
        if ($Negate) {
            $succeeded = -not $succeeded
        }
    
        $failureMessage = ''
    
        if (-not $succeeded) {
            if ($Negate) {
                $failureMessage = NotShouldBeFailureMessage -ActualValue $ActualValue -Expected $ExpectedValue -Because $Because
            }
            else {
                $failureMessage = ShouldBeFailureMessage -ActualValue $ActualValue -Expected $ExpectedValue -Because $Because
            }
        }
    
        return & $SafeCommands['New-Object'] psobject -Property @{
            Succeeded      = $succeeded
            FailureMessage = $failureMessage
        }
    }
    
    function ShouldBeFailureMessage($ActualValue, $ExpectedValue, $Because) {
        # This looks odd; it's to unroll single-element arrays so the "-is [string]" expression works properly.
        $ActualValue = $($ActualValue)
        $ExpectedValue = $($ExpectedValue)
    
        if (-not (($ExpectedValue -is [string]) -and ($ActualValue -is [string]))) {
            return "Expected $(Format-Nicely $ExpectedValue),$(Format-Because $Because) but got $(Format-Nicely $ActualValue)."
        }
        <#joining the output strings to a single string here, otherwise I get
           Cannot find an overload for "Exception" and the argument count: "4".
           at line: 63 in C:\Users\nohwnd\github\pester\Functions\Assertions\Should.ps1
    
        This is a quickwin solution, doing the join in the Should directly might be better
        way of doing this. But I don't want to mix two problems.
        #>
        (Get-CompareStringMessage -Expected $ExpectedValue -Actual $ActualValue -Because $Because) -join "`n"
    }
    
    function NotShouldBeFailureMessage($ActualValue, $ExpectedValue, $Because) {
        return "Expected $(Format-Nicely $ExpectedValue) to be different from the actual value,$(Format-Because $Because) but got the same value."
    }
    
    Add-AssertionOperator -Name               Be `
        -InternalName       Should-Be `
        -Test               ${function:Should-Be} `
        -Alias              'EQ' `
        -SupportsArrayInput
    
    #BeExactly
    function Should-BeExactly($ActualValue, $ExpectedValue, $Because) {
        <#
    .SYNOPSIS
    Compares one object with another for equality and throws if the
    two objects are not the same. This comparison is case sensitive.
    
    .EXAMPLE
    $actual = "Actual value"
    PS C:\>$actual | Should -Be "Actual value"
    
    This test will pass. The two strings are identical.
    
    .EXAMPLE
    $actual = "Actual value"
    PS C:\>$actual | Should -Be "actual value"
    
    This test will fail, as the two strings do not match case sensitivity.
    #>
        [bool] $succeeded = ArraysAreEqual $ActualValue $ExpectedValue -CaseSensitive
    
        if ($Negate) {
            $succeeded = -not $succeeded
        }
    
        $failureMessage = ''
    
        if (-not $succeeded) {
            if ($Negate) {
                $failureMessage = NotShouldBeExactlyFailureMessage -ActualValue $ActualValue -ExpectedValue $ExpectedValue -Because $Because
            }
            else {
                $failureMessage = ShouldBeExactlyFailureMessage -ActualValue $ActualValue -ExpectedValue $ExpectedValue -Because $Because
            }
        }
    
        return New-Object psobject -Property @{
            Succeeded      = $succeeded
            FailureMessage = $failureMessage
        }
    }
    
    function ShouldBeExactlyFailureMessage($ActualValue, $ExpectedValue, $Because) {
        # This looks odd; it's to unroll single-element arrays so the "-is [string]" expression works properly.
        $ActualValue = $($ActualValue)
        $ExpectedValue = $($ExpectedValue)
    
        if (-not (($ExpectedValue -is [string]) -and ($ActualValue -is [string]))) {
            return "Expected exactly $(Format-Nicely $ExpectedValue),$(Format-Because $Because) but got $(Format-Nicely $ActualValue)."
        }
        <#joining the output strings to a single string here, otherwise I get
           Cannot find an overload for "Exception" and the argument count: "4".
           at line: 63 in C:\Users\nohwnd\github\pester\Functions\Assertions\Should.ps1
    
        This is a quickwin solution, doing the join in the Should directly might be better
        way of doing this. But I don't want to mix two problems.
        #>
        (Get-CompareStringMessage -Expected $ExpectedValue -Actual $ActualValue -CaseSensitive -Because $Because) -join "`n"
    }
    
    function NotShouldBeExactlyFailureMessage($ActualValue, $ExpectedValue, $Because) {
        return "Expected $(Format-Nicely $ExpectedValue) to be different from the actual value,$(Format-Because $Because) but got exactly the same value."
    }
    
    Add-AssertionOperator -Name               BeExactly `
        -InternalName       Should-BeExactly `
        -Test               ${function:Should-BeExactly} `
        -Alias              'CEQ' `
        -SupportsArrayInput
    
    
    #common functions
    function Get-CompareStringMessage {
        param(
            [Parameter(Mandatory = $true)]
            [AllowEmptyString()]
            [String]$ExpectedValue,
            [Parameter(Mandatory = $true)]
            [AllowEmptyString()]
            [String]$Actual,
            [switch]$CaseSensitive,
            $Because
        )
    
        $ExpectedValueLength = $ExpectedValue.Length
        $actualLength = $actual.Length
        $maxLength = $ExpectedValueLength, $actualLength | & $SafeCommands['Sort-Object'] -Descending | & $SafeCommands['Select-Object'] -First 1
    
        $differenceIndex = $null
        for ($i = 0; $i -lt $maxLength -and ($null -eq $differenceIndex); ++$i) {
            $differenceIndex = if ($CaseSensitive -and ($ExpectedValue[$i] -cne $actual[$i])) {
                $i
            }
            elseif ($ExpectedValue[$i] -ne $actual[$i]) {
                $i
            }
        }
    
        [string]$output = $null
        if ($null -ne $differenceIndex) {
            "Expected strings to be the same,$(Format-Because $Because) but they were different."
    
            if ($ExpectedValue.Length -ne $actual.Length) {
                "Expected length: $ExpectedValueLength"
                "Actual length:   $actualLength"
                "Strings differ at index $differenceIndex."
            }
            else {
                "String lengths are both $ExpectedValueLength."
                "Strings differ at index $differenceIndex."
            }
    
            "Expected: '{0}'" -f ( $ExpectedValue | Expand-SpecialCharacters )
            "But was:  '{0}'" -f ( $actual | Expand-SpecialCharacters )
    
            $specialCharacterOffset = $null
            if ($differenceIndex -ne 0) {
                #count all the special characters before the difference
                $specialCharacterOffset = ($actual[0..($differenceIndex - 1)] |
                        & $SafeCommands['Where-Object'] {"`n", "`r", "`t", "`b", "`0" -contains $_} |
                        & $SafeCommands['Measure-Object'] |
                        & $SafeCommands['Select-Object'] -ExpandProperty Count)
            }
    
            '-' * ($differenceIndex + $specialCharacterOffset + 11) + '^'
        }
    }
    
    function Expand-SpecialCharacters {
        param (
            [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
            [AllowEmptyString()]
            [string[]]$InputObject)
        process {
            $InputObject -replace "`n", "\n" -replace "`r", "\r" -replace "`t", "\t" -replace "`0", "\0" -replace "`b", "\b"
        }
    }
    
    function ArraysAreEqual {
        param (
            [object[]] $First,
            [object[]] $Second,
            [switch] $CaseSensitive,
            [int] $RecursionDepth = 0,
            [int] $RecursionLimit = 100
        )
        $RecursionDepth++
    
        if ($RecursionDepth -gt $RecursionLimit) {
            throw "Reached the recursion depth limit of $RecursionLimit when comparing arrays $First and $Second. Is one of your arrays cyclic?"
        }
    
        # Do not remove the subexpression @() operators in the following two lines; doing so can cause a
        # silly error in PowerShell v3.  (Null Reference exception from the PowerShell engine in a
        # method called CheckAutomationNullInCommandArgumentArray(System.Object[]) ).
        $firstNullOrEmpty = ArrayOrSingleElementIsNullOrEmpty -Array @($First)
        $secondNullOrEmpty = ArrayOrSingleElementIsNullOrEmpty -Array @($Second)
    
        if ($firstNullOrEmpty -or $secondNullOrEmpty) {
            return $firstNullOrEmpty -and $secondNullOrEmpty
        }
    
        if ($First.Count -ne $Second.Count) {
            return $false
        }
    
        for ($i = 0; $i -lt $First.Count; $i++) {
            if ((IsArray $First[$i]) -or (IsArray $Second[$i])) {
                if (-not (ArraysAreEqual -First $First[$i] -Second $Second[$i] -CaseSensitive:$CaseSensitive -RecursionDepth $RecursionDepth -RecursionLimit $RecursionLimit)) {
                    return $false
                }
            }
            else {
                if ($CaseSensitive) {
                    $comparer = { param($Actual, $Expected) $Expected -ceq $Actual }
                }
                else {
                    $comparer = { param($Actual, $Expected) $Expected -eq $Actual }
                }
    
                if (-not (& $comparer $First[$i] $Second[$i])) {
                    return $false
                }
            }
        }
    
        return $true
    }
    
    function ArrayOrSingleElementIsNullOrEmpty {
        param ([object[]] $Array)
    
        return $null -eq $Array -or $Array.Count -eq 0 -or ($Array.Count -eq 1 -and $null -eq $Array[0])
    }
    
    function IsArray {
        param ([object] $InputObject)
    
        # Changing this could cause infinite recursion in ArraysAreEqual.
        # see https://github.com/pester/Pester/issues/785#issuecomment-322794011
        return $InputObject -is [Array]
    }
    
    function ReplaceValueInArray {
        param (
            [object[]] $Array,
            [object] $Value,
            [object] $NewValue
        )
    
        foreach ($object in $Array) {
            if ($Value -eq $object) {
                $NewValue
            }
            elseif (@($object).Count -gt 1) {
                ReplaceValueInArray -Array @($object) -Value $Value -NewValue $NewValue
            }
            else {
                $object
            }
        }
    }
    
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUYuL1QX6V7O6JS0rQ2xLEiRBG
    # KMSggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # 4W3h9TUT4sGlhFzHSrrEjCDRbsIwDQYJKoZIhvcNAQEBBQAEggEAYoBynEqMInLv
    # 2ZFqdPZjvc+wUQXOYYiO61XitgxpM7LNSniFasHZB4zCDl71/jxCb6eoGGbcel46
    # /I0UZzU2INnjHNtJLcbydEaZNlaFdvNyFXNm7VePer2U1VmwsgPy8TarK4n+NKpW
    # yphUThc63lEzd2euz/SNX9nDbQQlZoP6RlTjuNjtB22QJwyLzGlLnZtmFpkdXgmo
    # s73pA8fCW46nSZGc67zBrJpRGPzS7VZlFrfN8RAGVQAUa2xanc5/5lPAKWY3sgr0
    # 9TveL9bgIo7UGuDa/w422/7XEh/8A35xQRU6FfoKtFuxY/6oVEmapfi+3MxFuCs5
    # EoKTtanSV6GCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzQ3WjAjBgkqhkiG9w0BCQQx
    # FgQU751frU1r2TeCR9THRznSkyZ+CQYwDQYJKoZIhvcNAQEBBQAEggEAoI03YHy2
    # C5p117PkVSOT1DtWx9d6iozjLe4PxDlWSB7gaHn7rRwnO1vQMP+iDz5chtm7YymU
    # JHrD7kHzoIHQjcwCsUwKW5pceve6KeEPgoQtVciyFd2TMwGgvFrjzTVZnTn6IhyO
    # c8a49jJg5MYc/GaiTzW2XaDvOwnYr7AQme2sJjLCxcmmbPUtMBRmwJLUuSdgeEqB
    # ZqwzdLVgfZ25cT1DiWkrukl1QjMoZseHhdqLyq9AUXRkBa2E8uOIZmUQo1ajHGMf
    # 0+7FSKuyHmcoL3pSBPiRnbFafT9jEgCQUuwmE3Jwq6NcrzQwFsBhCyQ5W2c9NKZ/
    # DNyt+VYDlJaQHA==
    # SIG # End signature block
    
  • tools\en-US\RSpec.psd1 Show
    @{
        StartMessage      = "Executing all tests in '{0}'"
        FilterMessage     = ' matching test name {0}'
        TagMessage        = ' with Tags {0}'
        MessageOfs        = "', '"
    
        CoverageTitle     = 'Code coverage report:'
        CoverageMessage   = 'Covered {2:P2} of {3:N0} analyzed {0} in {4:N0} {1}.'
        MissedSingular    = 'Missed command:'
        MissedPlural      = 'Missed commands:'
        CommandSingular   = 'Command'
        CommandPlural     = 'Commands'
        FileSingular      = 'File'
        FilePlural        = 'Files'
    
        Describe          = 'Describing {0}'
        Script            = 'Executing script {0}'
        Context           = 'Context {0}'
        Margin            = '  '
        Timing            = 'Tests completed in {0}'
    
        # If this is set to an empty string, the count won't be printed
        ContextsPassed    = ''
        ContextsFailed    = ''
    
        TestsPassed       = 'Tests Passed: {0}, '
        TestsFailed       = 'Failed: {0}, '
        TestsSkipped      = 'Skipped: {0}, '
        TestsPending      = 'Pending: {0}, '
        TestsInconclusive = 'Inconclusive: {0} '
    }
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUUrvIQ40s9TV36NgmAXfCyT+j
    # zfiggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # ejRQ9vqlmetfDBzOgyD+0gCb7dEwDQYJKoZIhvcNAQEBBQAEggEAfg0KEEpbUdL9
    # OysZp6j34VT6kzrQNBea8H9pkpTB2w99hjQ0amNn+9WE+PLRMCuyHo4hF1GY6eg4
    # YB99evQVcP6qGItOUp+l8a0oGjzhDZ69lkO9VMyQ10SPAbCPbKmhhRmbSowdUkpP
    # BYv5GGl4ZWdHgGBMmwdl5bcu0hxevqMkA3OuGApaBrwl6LZXEswB8lOsnP0HK76Z
    # pflbDM2dyGA6WAjBHdeDXDgU/pBFu3GpP6fS/gwjrOk7vxCz9jv7N1PWHUHEQpUv
    # BLzvCfDLExUSvwsnEyu/Npw7xyXlmQ31w2jM1ouVE5LcYUBNu6KFOyP2VRhF387J
    # jTaC9wqM5aGCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzMzWjAjBgkqhkiG9w0BCQQx
    # FgQUuAlLwVZojjx2lRi8kWnn2OFa5MMwDQYJKoZIhvcNAQEBBQAEggEACtONcSpZ
    # w7FT+QNz1Ch1fLYQfoc/y+CJSAY1jtzs0rFlgQx7VK0O5sK1e5BO2nJpaGZOLFKw
    # RGqefPp4xtw+R4bdk7sVwbdBb1zxi+Da2i5nrjHRvNi1jgxKtNzIhKKeb+HT8ROx
    # ibj4X736ubHu79jK1nBrmwuqVBjJP7u+PDhV3OSnxMSRBxtVHJFkQRMxhjjpXrLq
    # U3i5ZPGMyWaOmyOwdUm3fzHl6oLGF6uf3Hnza38uJWvQ+WTwYFn7ufcp84vKxUgV
    # 5TOMJfb429FvM6IHM71rGLpwvd4hGiTxp4HKJig12mUohqkD2titEE1AxluW/gRz
    # ZnMQ9WVJrY2+wg==
    # SIG # End signature block
    
  • tools\en-US\Gherkin.psd1 Show
    @{
        StartMessage      = "Testing all features in '{0}'"
        FilterMessage     = " for scenarios matching '{0}'"
        TagMessage        = " with tags: '{0}'"
        MessageOfs        = "', '"
    
        CoverageTitle     = "Code coverage report:"
        CoverageMessage   = "Covered {2:P2} of {3:N0} analyzed {0} in {4:N0} {1}."
        MissedSingular    = 'Missed command:'
        MissedPlural      = 'Missed commands:'
        CommandSingular   = 'Command'
        CommandPlural     = 'Commands'
        FileSingular      = 'File'
        FilePlural        = 'Files'
    
        Describe          = "Feature: {0}"
        Context           = "Scenario: {0}"
        Margin            = "  "
        Timing            = "Testing completed in {0}"
    
        # If this is set to an empty string, the count won't be printed
        ContextsPassed    = "Scenarios Passed: {0} "
        ContextsFailed    = "Failed: {0}"
        TestsPassed       = "Steps Passed: {0} "
        TestsFailed       = "Failed: {0} "
        TestsSkipped      = 'Skipped: {0} '
        TestsPending      = 'Pending: {0} '
        TestsInconclusive = 'Inconclusive: {0} '
    }
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUYsZXTVKvcscQ6pNEuikkzN7n
    # /NeggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0
    # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2Vy
    # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5n
    # Q0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAFltMO2WO9L/
    # fLYIbzeQIilLoH97l9PYQAPz5uNh4R8l5w6Y/SgusY3+k+KaNONXSTcSL1KP9Pn3
    # 2y11xqFwdrJbRxC8i5x2KFvGDGkvpDWFsX24plq5brRL+qerkyTwRgSRUiU/luvq
    # BTYQ/eQmgikkIB6l7f6m2An8qtOkNfDM0D/eVJS3+/TRSMIPmBp9Ubktacp8sNIK
    # JacAkVl1zjucvVhyuWOFsIFtPn25XsiNu4d87pUyMzm8Vehyl1xxLNH/6cqxCkyG
    # FXCrav1knrz22qD5b8wrwUYnmCt37BeBX6KvpSXpafDdAok5QkPs7TeJVcVVPdb4
    # tqaLNvGOpBgwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3
    # DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX
    # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy
    # ZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIx
    # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
    # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
    # RCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    # AQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl
    # +YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQz
    # UHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNx
    # PqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqr
    # hPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItq
    # cyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/
    # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEF
    # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD
    # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny
    # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig
    # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v
    # dENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc
    # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4E
    # FgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL
    # p6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0c
    # LToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9x
    # jmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpx
    # KAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUI
    # QjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhiz
    # gZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggZq
    # MIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJ
    # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
    # aWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAe
    # Fw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREw
    # DwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJl
    # c3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CC
    # NeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4Xp
    # X6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9
    # Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu
    # 5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDI
    # jegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawC
    # wO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
    # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGh
    # BglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
    # dC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAA
    # bwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMA
    # dABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgA
    # ZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgA
    # ZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4A
    # dAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAA
    # YQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIA
    # ZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAf
    # BgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJ
    # Mp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGln
    # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6
    # Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcG
    # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
    # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
    # aUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNN
    # siaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3
    # +puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i
    # 2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHd
    # FMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sK
    # HOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvj
    # jz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZI
    # hvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
    # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
    # dXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFow
    # YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
    # d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBD
    # QS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBz
    # QHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r
    # 7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD
    # /6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z
    # 8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2
    # zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9
    # BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsG
    # AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCC
    # AdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEW
    # Lmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w
    # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
    # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
    # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
    # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
    # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
    # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
    # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
    # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQI
    # MAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
    # cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
    # ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw
    # OqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
    # RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
    # Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+
    # Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3
    # DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKy
    # XGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+er
    # Ys37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+c
    # dkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeS
    # DY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGt
    # STGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkG
    # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
    # Z2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
    # ZGUgU2lnbmluZyBDQQIQAkpwj7JyQh8pn8abOhJIUDAJBgUrDgMCGgUAoHgwGAYK
    # KwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
    # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
    # kotvb68dzReltbz1cQaSs8dI13QwDQYJKoZIhvcNAQEBBQAEggEAkllXqTAZ6MZM
    # dgUcmw0/vA1141aAtD8LOIgYcRrA1NS4bGG3xfHS0WJaSU3YbT5IL9Gws38WUegA
    # F71/SNNtqQQ0k1KNsZ8hBFOZZ0AeYUqUyEuv0reW6CbTzw6lXAmrBMhmQ8NJ85Mc
    # tBo0XVHfhV1A7S6JFzsQkXcOcLruX73MregQUykCbAb3jrmjlkwzPensP094xNjY
    # mu0S+ZwJE8ROTnAPDLTeOQOqzdZRaIWzXMSxPeXTz+2/p42DnC+CurkRAhuMtXJ8
    # WlCMQEiGvLtJX+oG2lfh106KKWgM7Q785xm4HLcYHYXhRER7NPfMVYVA1JTnp2q5
    # 6PvnP4+gvKGCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNV
    # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
    # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGa
    # Ajr/WLFr1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
    # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkwMzAzMDk0NzMyWjAjBgkqhkiG9w0BCQQx
    # FgQUtUxz9pYvTK7CdXgs4U08uVIvohswDQYJKoZIhvcNAQEBBQAEggEAYdG0noWX
    # mnHh93zNrec0aMa/lTjNTmgTYdkMPH6c7O58mVXOzC5jWPfrGJqztCeumYILZaij
    # jyFrpA8veqHfGDmE5vJ9oOQrL/uBM0PtsbTzO0jnZgHBl+8kOgMl8i/AEarOoSnr
    # j8CgidThtjViG5PzS3WTdyfqKzNbpKiwHCMNCFfiPzmxR4jkdY2QmQCFm7BHB3OM
    # uRPAt2mqlxD2v0JMC6T3zgkCmaJ2ny5AOW/qKyOe0CP0Bilq0kyvtSUYpNEIHir8
    # dLx8fRFXJo0S+5ZFAChRBa6vOxT7HxIC/puuq9rZ+J6izMJrhrs45i0B9AWrIo+2
    # OLTtwMWnRDEgGw==
    # SIG # End signature block
    
  • tools\en-US\about_TestDrive.help.txt Show
    TOPIC
        about_TestDrive
    
    SHORT DESCRIPTION
        A PSDrive for file activity limited to the scope of a singe Describe or
        Context block.
    
    LONG DESCRIPTION
        A test may need to work with file operations and validate certain types of
        file activities. It is usually desirable not to perform file activity tests
        that will produce side effects outside of an individual test. Pester
        creates a PSDrive inside the user's temporary drive that is accessible via a
        names PSDrive TestDrive:. Pester will remove this drive after the test
        completes. You may use this drive to isolate the file operations of your
        test to a temporary store.
    
    EXAMPLE
        function Add-Footer($path, $footer) {
            Add-Content $path -Value $footer
        }
    
        Describe "Add-Footer" {
            $testPath="TestDrive:\test.txt"
            Set-Content $testPath -value "my test text."
            Add-Footer $testPath "-Footer"
            $result = Get-Content $testPath
    
            It "adds a footer" {
                (-join $result).Should.Be("my test text.-Footer")
            }
        }
    
        When this test completes, the contents of the TestDrive PSDrive will
        be removed.
    
    SEE ALSO
        Context
        Describe
        It
        about_Should
    
  • tools\en-US\about_Should.help.txt Show
    TOPIC
        about_Should
    
    SHORT DESCRIPTION
        Provides assertion convenience methods for comparing objects and throwing
        test failures when test expectations fail.
    
    LONG DESCRIPTION
        Should is an Extension of System.Object and can be used as a native type
        inside Describe blocks. The various Should member methods can be invoked
        directly from an object being compared. It is typically used in individual
        It blocks to verify the results of an expectation. The Should method is
        typically called from the "actual" object being compared and takes the
        expected" object as a parameter. Should includes several members that
        perform various comparisons of objects and will throw a PesterFailure when
        the objects do not evaluate to be comparable.
    
    SHOULD MEMBERS
      GENERAL
        Be
            Compares one object with another for equality and throws if the two
            objects are not the same.
    
            $actual="Actual value"
            $actual | Should -Be "actual value" # Test will pass
            $actual | Should -Be "not actual value"  # Test will fail
    
        BeExactly
            Compares one object with another for equality and throws if the two objects are not the same.  This comparison is case sensitive.
    
            $actual="Actual value"
            $actual | Should -BeExactly "Actual value" # Test will pass
            $actual | Should -BeExactly "actual value" # Test will fail
    
        BeNullOrEmpty
            Checks values for null or empty (strings). The static [String]::IsNullOrEmpty() method is used to do the comparison.
    
            $null | Should -BeNullOrEmpty # Test will pass
            $null | Should -Not -BeNullOrEmpty # Test will fail
            @()   | Should -BeNullOrEmpty # Test will pass
            ""    | Should -BeNullOrEmpty # Test will pass
        BeTrue
            Asserts that the value is true, or truthy.
    
            $true | Should -BeTrue
            1 | Should -BeTrue
            1,2,3 | Should -BeTrue
    
        BeFalse
            Asserts that the value is false of falsy.
    
            $false | Should -BeFalse
            0 | Should -BeFalse
            $null | Should -BeFalse
    
        BeOfType, HaveType
            Asserts that the actual value should be an object of a specified type (or a subclass of the specified type) using PowerShell's -is operator:
    
            $actual = Get-Item $env:SystemRoot
            $actual | Should -BeOfType System.IO.DirectoryInfo   # Test will pass; object is a DirectoryInfo
            $actual | Should -BeOfType System.IO.FileSystemInfo  # Test will pass; DirectoryInfo base class is FileSystemInfo
            $actual | Should -HaveType System.IO.FileSystemInfo  # Test will pass; DirectoryInfo base class is FileSystemInfo
    
            $actual | Should -BeOfType System.IO.FileInfo        # Test will fail; FileInfo is not a base class of DirectoryInfo
    
    
      TEXT
        BeLike
            Asserts that the actual value matches a wildcard pattern using PowerShell's -like operator.  This comparison is not case-sensitive.
    
            $actual="Actual value"
            $actual | Should -BeLike "actual *" # Test will pass
            $actual | Should -BeLike "not actual *" # Test will fail
    
        BeLikeExactly
    
            Asserts that the actual value matches a wildcard pattern using PowerShell's -like operator.  This comparison is case-sensitive.
    
            $actual="Actual value"
            $actual | Should -BeLikeExactly "Actual *" # Test will pass
            $actual | Should -BeLikeExactly "actual *" # Test will fail
    
        Match
            Uses a regular expression to compare two objects. This comparison is not case sensitive.
    
            "I am a value" | Should -Match "I Am" # Test will pass
            "I am a value" | Should -Match "I am a bad person" # Test will fail
    
            Tip: Use [regex]::Escape("pattern") to match the exact text.
    
            "Greg" | Should -Match ".reg" # Test will pass
            "Greg" | Should -Match ([regex]::Escape(".reg")) # Test will fail
    
        MatchExactly
            Uses a regular expression to compare two objects.  This comparison is case sensitive.
    
            "I am a value" | Should -MatchExactly "I am" # Test will pass
            "I am a value" | Should -MatchExactly "I Am" # Test will fail
    
      COMPARISON
        BeGreaterThan
            Asserts that a number (or other comparable value) is greater than an expected value. Uses PowerShell's -gt operator to compare the two values.
    
            2 | Should -BeGreaterThan 0
    
        BeGreaterOrEqual
            Asserts that a number (or other comparable value) is greater than or equal to an expected value. Uses PowerShell's -ge operator to compare the two values.
    
            2 | Should -BeGreaterOrEqual 0
            2 | Should -BeGreaterOrEqual 2
    
        BeLessThan
            Asserts that a number (or other comparable value) is lower than an expected value. Uses PowerShell's -lt operator to compare the two values.
    
            1 | Should -BeLessThan 10
    
        BeLessOrEqual
            Asserts that a number (or other comparable value) is lower than, or equal to an expected value. Uses PowerShell's -le operator to compare the two values.
    
            1 | Should -BeLessOrEqual 10
            10 | Should -BeLessOrEqual 10
    
      COLLECTION
        BeIn
            Asserts that a collection of values contain a specific value. Uses PowerShell's -contains operator to confirm.
    
            1 | Should -BeIn @(1,2,3,'a','b','c')
    
        Contain
            Asserts that collection contains a specific value. Uses PowerShell's -contains operator to confirm.
    
            1,2,3 | Should -Contain 1
    
        HaveCount
            Asserts that a collection has the expected amount of items.
    
            1,2,3 | Should -HaveCount 3
    
      FILE
        Exist
            Does not perform any comparison but checks if the object calling Exist
            is present in a PS Provider. The object must have valid path syntax. It
            essentially must pass a Test-Path call.
    
            $actual=(Dir . )[0].FullName
            Remove-Item $actual
            $actual | Should -Exist # Test will fail
    
        FileContentMatch
            Checks to see if a file contains the specified text.  This search is not case sensitive and uses regular expressions.
    
            Set-Content -Path TestDrive:\file.txt -Value 'I am a file.'
            'TestDrive:\file.txt' | Should -FileContentMatch 'I Am' # Test will pass
            'TestDrive:\file.txt' | Should -FileContentMatch '^I.*file\.$' # Test will pass
    
            'TestDrive:\file.txt' | Should -FileContentMatch 'I Am Not' # Test will fail
    
            Tip: Use [regex]::Escape("pattern") to match the exact text.
    
            Set-Content -Path TestDrive:\file.txt -Value 'I am a file.'
            'TestDrive:\file.txt' | Should -FileContentMatch 'I.am.a.file' # Test will pass
            'TestDrive:\file.txt' | Should -FileContentMatch ([regex]::Escape('I.am.a.file')) # Test will fail
    
        FileContentMatchExactly
            Checks to see if a file contains the specified text.  This search is case sensitive and uses regular expressions to match the text.
    
            Set-Content -Path TestDrive:\file.txt -Value 'I am a file.'
            'TestDrive:\file.txt' | Should -FileContentMatch 'I am' # Test will pass
            'TestDrive:\file.txt' | Should -FileContentMatch 'I Am' # Test will fail
    
        FileContentMatchMultiline
            As opposed to FileContentMatch and FileContentMatchExactly operators, FileContentMatchMultiline presents content of the file
            being tested as one string object, so that the expression you are comparing it to can consist of several lines.
    
            $Content = "I am the first line.`nI am the second line."
            Set-Content -Path TestDrive:\file.txt -Value $Content -NoNewline
            'TestDrive:\file.txt' | Should -FileContentMatchMultiline 'first line\.\r?\nI am' # Test will pass
            'TestDrive:\file.txt' | Should -FileContentMatchMultiline '^I am the first.*\n.*second line\.$' # Test will pass.
    
            When using FileContentMatchMultiline operator, '^' and '$' represent the beginning and end of the whole file,
            instead of the beginning and end of a line.
    
            $Content = "I am the first line.`nI am the second line."
            Set-Content -Path TestDrive:\file.txt -Value $Content -NoNewline
            'TestDrive:\file.txt' | Should -FileContentMatchMultiline '^I am the first line\.$' # Test will fail.
    
    
      EXCEPTIONS
        Throw
            Checks if an exception was thrown. Enclose input in a script block.
    
            { foo } | Should -Throw # Test will pass
            { $foo = 1 } | Should -Throw # Test will fail
            { foo } | Should -Not -Throw # Test will fail
            { $foo = 1 } | Should -Not -Throw # Test will pass
    
            Warning: The input object must be a ScriptBlock, otherwise it is processed outside of the assertion.
    
            Get-Process -Name "process" -ErrorAction Stop | Should -Throw # Should pass, but the exception thrown by Get-Process causes the test to fail.
    
      NEGATIVE ASSERTIONS
        Any of the Should operators described above can be negated by using the word "Not" before the operator.  For example:
    
        'one' | Should -Not -Be 'Two'
        { Get-Item $env:SystemRoot } | Should -Not -Throw
    
      USING SHOULD IN A TEST
    
        function Add-Numbers($a, $b) {
            return $a + $b
        }
    
        Describe "Add-Numbers" {
    
            It "adds positive numbers" {
                $sum = Add-Numbers 2 3
                $sum | Should -Be 3
            }
        }
    
        This test will fail since 3 will not be equal to the sum of 2 and 3.
    
      BECAUSE
        Every built in assertion allows you to specify -Because parameter, to give more meaning to your tests.
    
        function Get-Group { $null }
        $groups = 1..10 | Get-Group -Size 3
        $groups | Should -HaveCount 4 -Because "because 10 items are split into three groups with 3 members and one extra group with 1 member"
    
        Which fails with: "Expected a collection with size {4}, because 10 items are split into three groups with 3 members and one extra group with 1 member, but got collection with size {1} [].
    
    SEE ALSO
      Describe
      Context
      It
    
  • tools\en-US\about_Pester.help.txt Show
    TOPIC
        about_Pester
    
    SHORT DESCRIPTION
        Pester is a test framework for Windows PowerShell. Use the Pester language
        and its commands to write and run tests that verify that your scripts and
        modules work as designed.
    
        Pester 3.4.0 supports Windows PowerShell 2.0 and greater.
    
    LONG DESCRIPTION
        Pester introduces a professional test framework for Windows PowerShell
        commands. You can use Pester to test commands of any supported type,
        including scripts, cmdlets, functions, CIM commands, workflows, and DSC
        resources, and test these commands in modules of all types.
    
        Each Pester test compares actual to expected output using a collection of
        comparison operators that mirror the familiar operators in Windows
        PowerShell. In this way, Pester supports "dynamic testing", that is, it
        tests the code while it's running, instead of just evaluating code syntax
        ("static testing").
    
        Once your Pester tests are written are verified to work correctly, you can
        run them automatically or on demand to verify that the output didn't change
        and that any code changes did not introduce errors. You can also add your
        tests to the build scripts of a continuous integration system, and add new
        tests at any time.
    
    
     WHAT CAN PESTER TEST?
        Pester is designed to support "test-driven development" (TDD), in which you
        write and run tests before writing your code, thereby using the test as a
        code specification.
    
        It also supports "behavior-driven development" (BDD), in which the tests
        verify the behavior and output of the code, and the user experience,
        independent of its implementation. This lets you change the implementation
        and use the test to verify that the behavior is unchanged.
    
        You can use Pester to write "unit tests" that test individual functions in
        isolation and "integration tests" that verify that functions can be used
        together to generate expected results.
    
        Pester creates and manages a temporary drive (PSDrive named TestDrive:) that
        you can use to simulate a file system. For more information, see
        about_TestDrive.
    
        Pester also has "mocking" commands that replace the actual output of
        commands with output that you specify. Mocking lets you test your commands
        with varied input without creating and maintaining fake entries in a file
        or database, or commenting-out and inserting code just for testing. For more
        information, see about_Mocking.
    
    
     THE PESTER LANGUAGE
        To make it easier to write tests, Pester uses a language especially designed
        for testing. This "domain-specific language" (DSL) hides the standard
        verb-noun syntax of PowerShell commands.
    
        To make the language more fluent, the command parameters are positional, so
        you don't typically use parameter names.
    
        For example, this "gets all widgets" test uses the Pester language,
        including its "It", "Should", and "Be" commands. The test verifies that the
        actual output of the Get-Widget cmdlet is the same as the expected value in
        the $allWidgets variables.
    
            It "gets all widgets" {
               Get-Widget | Should -Be $allWidgets
            }
    
    
        To learn the Pester language, start by reading the following About and
        cmdlet help topics:
    
        -- Describe:     Creates a required test container.
        -- Context:      Creates an optional scoped test sub-container.
        -- It:           Creates a test.
        -- about_Should  Compares actual to expected values. This topic also
                         lists all valid values of Be, which specify the
                         comparison operator used in the test.
    
    
    
     HOW TO CREATE TEST FILES
        To start using Pester, create a script and a test file that tests the
        script. If you already have a script, you can create a test file for it.
    
        Pester test files are Windows PowerShell scripts with a .Tests.ps1 file name
        extension. The distinctive file name extension enables Pester to identify
        tests and distinguish them from other scripts.
    
        Typically, the test file and file it tests have the same base file name,
        such as:
    
            New-Log.ps1
            New-Log.Tests.ps1
    
        For a quick start, use the New-Fixture cmdlet in the Pester module. It
        creates a script with an empty function and a matching test file with a
        valid test.
    
        For example, this command creates a New-Log.ps1 script and a
        New-Log.Tests.ps1 test script in the C:\Scripts\LogScripts directory.
    
        New-Fixture -Path C:\Scripts\LogScripts -Name New-Log
    
            Directory: C:\Scripts\LogScripts
    
    
            Mode                LastWriteTime     Length Name
            ----                -------------     ------ ----
            -a----        4/18/2016   9:51 AM         30 New-Log.ps1
            -a----        4/18/2016   9:51 AM        262 New-Log.Tests.ps1
    
    
        The similar names do not automatically associate the test file and script
        file. The test file must include code to import ("dot-source") the
        functions, aliases, and variables in the script being tested into the scope
        of the test script.
    
        For example:
           . .\New-Log.ps1
        -or-
           . C:\Scripts\LogScripts\New-Log.ps1
    
    
        Many Pester test files, including the files that New-Fixture creates, begin with these
        statements.
    
            $here = Split-Path -Parent $MyInvocation.MyCommand.Path
            $sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.Tests\.', '.'
            . "$here\$sut"
    
        This code finds the current path of the test file at run time and saves it
        in the $here variable. Then, it finds the script based on the path in $here.
        This code assumes that the script has the same base name and is located in
        the same directory as the test file.
    
        You can use any code in the test file that finds the script, but be sure
        that the test file has the required *.Tests.ps1 file name extension.
    
    
    
     HOW TO RUN PESTER TESTS
        Pester tests are Windows PowerShell scripts (.ps1 files), so you can run
        them at the command line, or in any editor.
    
        Pester also has an Invoke-Pester cmdlet with useful parameters. By default,
        Invoke-Pester runs all the tests in a directory and all of its subdirectories
        recursively, but you can run selected tests by specifying a script name or
        name pattern, a test name, or a test tag.
    
        Invoke-Pester parameters also let you save the test output in NUnitXml or
        LegacyNUnitXml formats that are commonly used by reporting tools.
    
        For example, the following command runs all tests in the current directory
        and all subdirectories recursively. It writes output to the host, but does
        not generate any objects.
    
        Invoke-Pester
    
        In contrast, this command runs only the tests in the New-Log.Tests.ps1 file
        that have the 'EventVwr' tag. It writes the test results as custom objects
        and saves them in NUnitXml format in the NewLogTests.xml file. It also runs
        an optional code coverage test to verify that all lines in the script ran
        at least once during the tests.
    
        Invoke-Pester -Script C:\Tests\New-Log.Tests.ps1 `
              -Tag EventVwr -OutputFile .\NewLogTests.xml -OutputFormat NUnitXml `
              -CodeCoverage
    
    
        To run the New-Log.Tests.ps1 file that New-Fixture created, change to its
        local directory or a parent directory, and run Invoke-Pester. You can also
        use the Script parameter of Invoke-Pester to run only the New-Log.Tests.ps1
        test.
    
            PS C:\Scripts> Invoke-Pester -Script .\New-Log.Tests.ps1
    
        For more information about Invoke-Pester, type: Get-Help Invoke-Pester
    
    
     EXAMPLE
        For your first Pester test, use the New-Fixture cmdlet to create a script
        file and matching test file.
    
        For example:
    
            New-Fixture -Path C:\TestPester -Name Get-Hello
    
            Directory: C:\TestPester
    
    
            Mode                LastWriteTime         Length Name
            ----                -------------         ------ ----
            -a----        4/18/2016   9:51 AM             30 Get-Hello.ps1
            -a----        4/18/2016   9:51 AM            262 Get-Hello.Tests.ps1
    
    
        The Get-Hello.ps1 script contains an empty Get-Hello.ps1 function.
    
            function Get-Hello {}
    
        The Get-Hello.Tests.ps1 file contains an empty Pester test that is named
        for the Get-Hello function.
    
            Describe "Get-Hello" {
                It "does something useful" {
                    $true | Should -Be $false
                }
            }
    
        To run the test, use Invoke-Pester. For example,
    
           Invoke-Pester C:\TestPester
    
        When you run the test, it fails by design, because Should compares $True to
        $False using the equal operator ("Be") and $True doesn't equal $False.
    
    
        To start testing the Get-Hello function, change $True to Get-Hello and
        $False to "Hello". Now, the test compares the output of Get-Hello output to
        'hello'.
    
        It should still fail, because Get-Hello doesn't return anything.
    
            Describe "New-Log" {
                It "does something useful" {
                    Get-Hello | Should -Be 'Hello'
                }
            }
    
    
        To make the test pass, change the Get-Hello function so it returns 'hello'.
        Then, in steps, change $False to more interesting values, then change the
        Get-Hello function output to make the test pass.
    
        You can also experiment with other comparison operators, such as the BeLike
        (supports wildcards) and BeExactly (case sensitive), and BeLikeExactly
        operators. For more, information about comparison operators in Pester, see
        about_Should.
    
    
     PESTER TEST OUTPUT
        When you run a test, Pester use a variation of Write-Host to write
        color-coded text to the console. You'll quickly learn to recognize the
        purple test names and green (passing) and red (failing) test results with
        the elapsed time of the test.
    
             Describing Get-Profile
              [+] Gets all profiles 156ms
              [+] Gets only profiles 24ms
    
        The output ends with a summary of the test results.
    
             Tests completed in 3.47s
             Passed: 20 Failed: 1 Skipped: 0 Pending: 0 Inconclusive: 0
    
        However, because Pester uses Write-Host, it does not write to the output
        stream (stdout), so there are no output objects to save in a variable or
        redirect to a file.
    
        To direct Pester to create custom objects, use its PassThru parameter. The
        result is a single PSCustomObject with a TestResult property that one
        TestResult custom object for each test in the test file.
    
        To save the custom objects to a file, use the OutputFile and OutputFormat
        parameters of Invoke-Pester, which save the output in NUnitXml and
        LegacyNUnitXml formats that are easy to parse and commonly used by reporting
        tools.
    
    
    
      REAL-WORLD EXAMPLES
        For help in writing Pester tests, examine the extensive collection of tests
        that Pester uses to verify its Windows PowerShell code.
    
        To find the Pester tests in the Pester module directory, type:
    
            dir <Pester_module_path>\*Tests.ps1 -Recurse
    
           -or-
    
        dir (Get-Module Pester -ListAvailable).ModuleBase -Include *Tests.ps1 -Recurse
    
    
    SEE ALSO
        Pester wiki: https://github.com/pester/pester/wiki
        Describe
        Context
        It
        New-Fixture
        Invoke-Pester
        about_Mocking
        about_Should
        about_TestDrive
    
  • tools\en-US\about_Mocking.help.txt Show
    TOPIC
        about_Mocking
    
    SHORT DESCRIPTION
        Pester provides a set of Mocking functions making it easy to fake dependencies
        and also to verify behavior. Using these mocking functions can allow you to
        "shim" a data layer or mock other complex functions that already have their
        own tests.
    
    LONG DESCRIPTION
        With the set of Mocking functions that Pester exposes, one can:
    
            - Mock the behavior of ANY PowerShell command.
            - Verify that specific commands were (or were not) called.
            - Verify the number of times a command was called with a set of specified
        parameters.
    
      MOCKING FUNCTIONS
      For detailed information about the functions in the Pester module, use Get-Help.
    
      Mock
        Mocks the behavior of an existing command with an alternate
        implementation.
    
      Assert-VerifiableMock
        Checks if any Verifiable Mock has not been invoked. If so, this will
        throw an exception.
    
      Assert-MockCalled
        Checks if a Mocked command has been called a certain number of times
        and throws an exception if it has not.
    
      EXAMPLE
        function Build ($version) {
            Write-Host "a build was run for version: $version"
        }
    
        function BuildIfChanged {
            $thisVersion = Get-Version
            $nextVersion = Get-NextVersion
            if ($thisVersion -ne $nextVersion) { Build $nextVersion }
            return $nextVersion
        }
    
        $here = Split-Path -Parent $MyInvocation.MyCommand.Path
        $sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path).Replace(".Tests.", ".")
        . "$here\$sut"
    
        Describe "BuildIfChanged" {
          Context "When there are Changes" {
            Mock Get-Version {return 1.1}
            Mock Get-NextVersion {return 1.2}
            Mock Build {} -Verifiable -ParameterFilter {$version -eq 1.2}
    
            $result = BuildIfChanged
    
            It "Builds the next version" {
              Assert-VerifiableMock
            }
            It "returns the next version number" {
              $result | Should -Be 1.2
            }
          }
          Context "When there are no Changes" {
            Mock Get-Version { return 1.1 }
            Mock Get-NextVersion { return 1.1 }
            Mock Build {}
    
            $result = BuildIfChanged
    
            It "Should not build the next version" {
              Assert-MockCalled Build -Times 0 -ParameterFilter {$version -eq 1.1}
            }
          }
        }
    
    
      MOCKING CALLS TO COMMANDS MADE FROM INSIDE SCRIPT MODULES
    
      Let's say you have code like this inside a script module (.psm1 file):
    
        function BuildIfChanged {
          $thisVersion = Get-Version
          $nextVersion = Get-NextVersion
          if ($thisVersion -ne $nextVersion) { Build $nextVersion }
          return $nextVersion
        }
    
        function Build ($version) {
          Write-Host "a build was run for version: $version"
        }
    
        # Actual definitions of Get-Version and Get-NextVersion are not shown here,
        # since we'll just be mocking them anyway. However, the commands do need to
        # exist in order to be mocked, so we'll stick dummy functions here
    
        function Get-Version { return 0 }
        function Get-NextVersion { return 0 }
    
        Export-ModuleMember -Function BuildIfChanged
    
      Beginning in Pester 3.0, there are two ways to write a unit test for a module that
      mocks the calls to Get-Version and Get-NextVersion from the module's BuildIfChanged
      command. The first is to inject mocks into a module:
    
      In these examples, the PSM1 file, MyModule.psm1 is installed in $env:PSModulePath on
      the local computer.
    
        Import-Module MyModule
    
        Describe "BuildIfChanged" {
          Context "When there are Changes" {
            Mock -ModuleName MyModule Get-Version { return 1.1 }
            Mock -ModuleName MyModule Get-NextVersion { return 1.2 }
    
            # To demonstrate that you can mock calls to commands other than functions
            # defined in the same module, we'll mock a call to Write-Host.
    
            Mock -ModuleName MyModule Write-Host {} -Verifiable -ParameterFilter {
                $Object -eq 'a build was run for version: 1.2'
            }
    
            $result = BuildIfChanged
    
            It "Builds the next version and calls Write-Host" {
              Assert-VerifiableMock
            }
    
            It "returns the next version number" {
              $result | Should -Be 1.2
            }
          }
    
          Context "When there are no Changes" {
            Mock -ModuleName MyModule Get-Version { return 1.1 }
            Mock -ModuleName MyModule Get-NextVersion { return 1.1 }
            Mock -ModuleName MyModule Build { }
    
            $result = BuildIfChanged
    
            It "Should not build the next version" {
              Assert-MockCalled Build -ModuleName MyModule -Times 0 -ParameterFilter {
                $version -eq 1.1
              }
            }
          }
        }
    
    
      In this sample test script, all calls to Mock and Assert-MockCalled have the
      -ModuleName MyModule parameter added. This tells Pester to inject the mock into the module scope,
      which causes any calls to those commands from inside the module to execute the mock instead.
    
      When you write your test script this way, you can mock commands that are called by the module's
      internal functions. However, your test script is still limited to accessing the public, exported
      members of the module. For example, you could not call the Build function directly.
    
      The InModuleScope command causes entire sections of your test script to execute inside the targeted
      script module. This gives you access to unexported members of the module. For example:
    
        Import-Module MyModule
    
        Describe "Unit testing the module's internal Build function:" {
          InModuleScope MyModule {
            $testVersion = 5.0
            Mock Write-Host { }
    
            Build $testVersion
    
            It 'Outputs the correct message' {
              Assert-MockCalled Write-Host -ParameterFilter {
                $Object -eq "a build was run for version: $testVersion"
              }
            }
          }
        }
    
      When using InModuleScope, you no longer need to specify a ModuleName parameter when calling
      Mock or Assert-MockCalled for commands in the module. You can also directly call the Build
      function that the module does not export.
    
    SEE ALSO
      Mock
      Assert-VerifiableMock
      Assert-MockCalled
      InModuleScope
      Describe
      Context
      It
    
      The following articles are useful for further understanding of Pester Mocks.
        Pester Mock and Test Drive, by Jakub Jareš:
          http://www.powershellmagazine.com/2014/09/30/pester-mock-and-testdrive/
        Pester and Mocking, by Mickey Gousset:
          http://www.systemcentercentral.com/day-53-pester-mocking/
        Mocking Missing Cmdlets with Pester, by Iain Brighton:
          http://virtualengine.co.uk/2015/mocking-missing-cmdlets-with-pester/
        Testing Mocked Output with Pester, by Steven Murawski:
          http://stevenmurawski.com/powershell/2014/02/testing-returned-objects-with-pester/
    
      The following articles are useful for deeper understanding of Mocking in general.
        Answer to the Question "What is the Purpose of Mock Objects" by Bert F:
          http://stackoverflow.com/a/3623574/5514075
        Mocks Aren't Stubs, by Martin Fowler:
          http://martinfowler.com/articles/mocksArentStubs.html
        The Art of Mocking, by Gil Zilberfeld:
          http://www.methodsandtools.com/archive/archive.php?id=122
    
  • tools\en-US\about_BeforeEach_AfterEach.help.txt Show
    TOPIC
        about_BeforeEach_AfterEach
    
    SHORT DESCRIPTION
        Describes the BeforeEach and AfterEach commands, which run a set of commands that you specify
        before or after every It block.
    
    LONG DESCRIPTION
        The the BeforeEach and AfterEach commands in the Pester module let you define setup and teardown
        tasks that are performed at the beginning and end of every It block. This can eliminate duplication of code
        in test scripts, ensure that each test is performed on a pristine state regardless of their
        order, and perform any necessary clean-up tasks after each test.
    
        BeforeEach and AfterEach blocks may be defined inside of any Describe or Context. If they
        are present in both a Context and its parent Describe, BeforeEach blocks in the Describe scope
        are executed first, followed by BeforeEach blocks in the Context scope. AfterEach blocks are
        the reverse of this, with the Context  AfterEach blocks executing before Describe.
    
        The script blocks assigned to BeforeEach and AfterEach are dot-sourced in the Context or Describe
        which contains the current It statement, so you don't have to worry about the scope of variable
        assignments. Any variables that are assigned values within a BeforeEach block can be used inside
        the body of the It block.
    
        BeforeAll and AfterAll are used the same way as BeforeEach and AfterEach, except that they are
        executed at the beginning and end of their containing Describe or Context block.  This is
        essentially syntactic sugar for the following arrangement of code:
    
          Describe 'Something' {
            try
            {
                <BeforeAll Code Here>
    
                <Describe Body>
            }
            finally
            {
                <AfterAll Code Here>
            }
          }
    
    
      SYNTAX AND PLACEMENT
        Unlike most of the commands in a Pester script, BeforeEach, AfterEach, BeforeAll and AfterAll blocks
        apply to the entire Describe or Context scope in which they are defined, regardless of the order of
        commands inside the Describe or Context. In other words, even if an It block appears before BeforeEach
        or AfterEach in the tests file, the BeforeEach and AfterEach will still be executed.  Likewise, BeforeAll
        code will be executed at the beginning of a Context or Describe block regardless of where it is found,
        and AfterAll code will execute at the end of the Context or Describe.
    
    
      EXAMPLES
        Describe 'Testing BeforeEach and AfterEach' {
            $afterEachVariable = 'AfterEach has not been executed yet'
    
            It 'Demonstrates that BeforeEach may be defined after the It command' {
                $beforeEachVariable | Should -Be 'Set in a describe-scoped BeforeEach'
                $afterEachVariable  | Should -Be 'AfterEach has not been executed yet'
                $beforeAllVariable  | Should -Be 'BeforeAll has been executed'
            }
    
            It 'Demonstrates that AfterEach has executed after the end of the first test' {
                $afterEachVariable | Should -Be 'AfterEach has been executed'
            }
    
            BeforeEach {
                $beforeEachVariable = 'Set in a describe-scoped BeforeEach'
            }
    
            AfterEach {
                $afterEachVariable = 'AfterEach has been executed'
            }
    
            BeforeAll {
                $beforeAllVariable = 'BeforeAll has been executed'
            }
          }
    
    SEE ALSO
        about_Pester
        about_Should
        about_Mocking
        about_TestDrive
        about_about_Try_Catch_Finally
        Describe
        Context
        Should
        It
        Invoke-Pester
    
  • tools\Dependencies\TypeClass\TypeClass.psm1 Show
    function Is-Value ($Value) {
        $Value = $($Value)
        $Value -is [ValueType] -or $Value -is [string] -or $value -is [scriptblock]
    }
    
    function Is-Collection ($Value) {
        # check for value types and strings explicitly
        # because otherwise it does not work for decimal
        # so let's skip all values we definitely know
        # are not collections
        if ($Value -is [ValueType] -or $Value -is [string]) {
            return $false
        }
    
        -not [object]::ReferenceEquals($Value, $($Value))
    }
    
    function Is-ScriptBlock ($Value) {
        $Value -is [ScriptBlock]
    }
    
    function Is-DecimalNumber ($Value) {
        $Value -is [float] -or $Value -is [single] -or $Value -is [double] -or $Value -is [decimal]
    }
    
    function Is-Hashtable ($Value) {
        $Value -is [hashtable]
    }
    
    function Is-Dictionary ($Value) {
        $Value -is [System.Collections.IDictionary]
    }
    
    
    function Is-Object ($Value) {
        # here we need to approximate that that object is not value
        # or any special category of object, so other checks might
        # need to be added
    
        -not ($null -eq $Value -or (Is-Value -Value $Value) -or (Is-Collection -Value $Value))
    }
    
    # SIG # Begin signature block
    # MIIcVgYJKoZIhvcNAQcCoIIcRzCCHEMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
    # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
    # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUICiyjxBewBLZ6r+DoKQLGcVi
    # QMqggheFMIIFDjCCA/agAwIBAgIQAkpwj7JyQh8pn8abOhJIUDANBgkqhkiG9w0B
    # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
    # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz
    # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE4MTEyNzAwMDAwMFoXDTE5MTIw
    # MjEyMDAwMFowSzELMAkGA1UEBhMCQ1oxDjAMBgNVBAcTBVByYWhhMRUwEwYDVQQK
    # DAxKYWt1YiBKYXJlxaExFTATBgNVBAMMDEpha3ViIEphcmXFoTCCASIwDQYJKoZI
    # hvcNAQEBBQADggEPADCCAQoCggEBAKgBHbFhyeivpcxqohppsNGucvZvAyvg3gKT
    # M1B6EpI18C6NN7FXWTPym9ffe1kS5ZeYDKW98NcOBArm28mdgip6WcUQ0qMt9lI8
    # EsTa4Ohlkj/AYYUdgh96zgIl/V+MIO3JVAY3OwkWjkfDKVbzrNG5IcO5yKfwnt8/
    # a238OS/VlFNsNELGW7XIQBD/rKrEDY8JZReIrkz6sGdba+3OcXBClp513JFniVgD
    # vOXo2RDUqtnpFuCdsthe8hWXtpbcjIpFykLzNcNA+2GIbwbBG5XKXsN0ZJsbrWVA
    # RiwNoDN+Fh3pe5rxGVfMDHdXt1I0KpJbFlGB4P7Sy2Mh5CTwRyUCAwEAAaOCAcUw
    # ggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBSw
    # +E81VeF9HSgNxUARWWqXFWZrZjAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI
    # KwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQu
    # Y29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRp
    # Z2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJ
    # YIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
    # bS9DUFMwCAYGZ4EMAQQBMIGEBggr