Windows/TestHarnesses/T1112_ModifyRegistry/Registry.Tests.ps1

Set-StrictMode -Version Latest

$TestScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
$ModuleRoot = Resolve-Path "$TestScriptRoot\..\..\..\"
$ModuleManifest = "$ModuleRoot\AtomicTestHarnesses.psd1"

Remove-Module [A]tomicTestHarnesses
Import-Module $ModuleManifest -Force -ErrorAction Stop

Describe 'Set-ATHRegistry' {
    BeforeAll {
        $Help = Get-Help -Name Set-ATHRegistry -Full
    
        $ExpectedTechniqueID = $null

        $RegistryKeyPath = 'AtomicTestHarnesses\T1112'
        $ValueName = 'TestValue'

        if ($Help.Synopsis.Split("`r`n")[-1] -match '^(?-i:Technique ID: )(?<TechniqueID>\S+) (?<TechniqueDescription>\(.+\))$') {
            $ExpectedTechniqueID = $Matches['TechniqueID']
        }
    }

    Context 'Validating error conditions' -Tag 'Unit', 'T1112' {
        It 'should throw an error when an attempt is made to create just a registry key with VBScript.' -Tag 'Unit', 'T1112' {
            { Set-ATHRegistry -Method VBScriptWscriptShellRegWrite -Hive HKCU -KeyPath 'Foo\Bar' -ErrorAction Stop } | Should -Throw
        }

        It 'should throw an error when an attempt is made to create just a registry key with JScript.' -Tag 'Unit', 'T1112' {
            { Set-ATHRegistry -Method JScriptWscriptShellRegWrite -Hive HKCU -KeyPath 'Foo\Bar' -ErrorAction Stop } | Should -Throw
        }

        It 'should not accept REG_MULTI_SZ when the VBScript RegWrite method is called.' -Tag 'Unit', 'T1112' {
            { Set-ATHRegistry -Method VBScriptWscriptShellRegWrite -Hive HKCU -KeyPath 'Foo\Bar' -ValueName 'Hello' -ValueMultiString 'hello', 'wrold' -ErrorAction Stop } | Should -Throw
        }

        It 'should not accept REG_MULTI_SZ when the JScript RegWrite method is called.' -Tag 'Unit', 'T1112' {
            { Set-ATHRegistry -Method JScriptWscriptShellRegWrite -Hive HKCU -KeyPath 'Foo\Bar' -ValueName 'Hello' -ValueMultiString 'hello', 'wrold' -ErrorAction Stop } | Should -Throw
        }

        It 'should not accept REG_BINARY when the VBScript RegWrite method is called.' -Tag 'Unit', 'T1112' {
            { Set-ATHRegistry -Method VBScriptWscriptShellRegWrite -Hive HKCU -KeyPath 'Foo\Bar' -ValueName 'Hello' -ValueBinary @(1,2,3) -ErrorAction Stop } | Should -Throw
        }

        It 'should not accept REG_BINARY when the JScript RegWrite method is called.' -Tag 'Unit', 'T1112' {
            { Set-ATHRegistry -Method JScriptWscriptShellRegWrite -Hive HKCU -KeyPath 'Foo\Bar' -ValueName 'Hello' -ValueBinary @(1,2,3) -ErrorAction Stop } | Should -Throw
        }

        It 'should not accept REG_QWORD when the VBScript RegWrite method is called.' -Tag 'Unit', 'T1112' {
            { Set-ATHRegistry -Method VBScriptWscriptShellRegWrite -Hive HKCU -KeyPath 'Foo\Bar' -ValueName 'Hello' -ValueQword 1 -ErrorAction Stop } | Should -Throw
        }

        It 'should not accept REG_QWORD when the JScript RegWrite method is called.' -Tag 'Unit', 'T1112' {
            { Set-ATHRegistry -Method JScriptWscriptShellRegWrite -Hive HKCU -KeyPath 'Foo\Bar' -ValueName 'Hello' -ValueQword 1 -ErrorAction Stop } | Should -Throw
        }

        It 'should not modify a registry key that already exists.' -Tag 'Unit', 'T1112' {
            { Set-ATHRegistry -Method WMI -Hive HKCU -KeyPath 'SOFTWARE' -ErrorAction Stop } | Should -Throw
        }

        It 'should not modify a registry value that already exists.' -Tag 'Unit', 'T1112' {
            { Set-ATHRegistry -Method WMI -Hive HKCR -KeyPath '.psc1' -ValueName 'Content Type' -ValueString 'foo' -ErrorAction Stop } | Should -Throw
        }
    }

    Context 'Expected artifacts and behaviors when exercising the attack technique' -Tag 'Technique', 'T1112' {
        It 'should create a new registry key using the following method: PowerShell' -Tag 'Technique', 'T1112' {
            # First, ensure that the key doesn't exist
            Remove-Item -Path "Registry::HKEY_CURRENT_USER\$RegistryKeyPath" -Force -ErrorAction Ignore

            $Result = Set-ATHRegistry -Method PowerShell -Hive HKCU -KeyPath $RegistryKeyPath -ErrorAction Stop
            
            $Result | Should -Not -BeNullOrEmpty

            $Result.TechniqueID          | Should -BeExactly $ExpectedTechniqueID
            $Result.TestSuccess          | Should -BeTrue
            $Result.Method               | Should -BeExactly 'PowerShell'
            $Result.SetKeyOnly           | Should -BeTrue
            $Result.KeyPath              | Should -BeExactly "HKEY_CURRENT_USER\$RegistryKeyPath"
            $Result.ValueName            | Should -BeNullOrEmpty
            $Result.ValueType            | Should -BeNullOrEmpty
            $Result.ValueContent         | Should -BeNullOrEmpty
            $Result.PreviousValueType    | Should -BeNullOrEmpty
            $Result.PreviousValueContent | Should -BeNullOrEmpty
            $Result.ProcessId            | Should -Be $PID
            $Result.ProcessPath          | Should -BeExactly ((Get-Process -Id $PID).MainModule.FileName)
            $Result.ProcessCommandLine   | Should -Not -BeNullOrEmpty
            $Result.TestSampleContent    | Should -Not -BeNullOrEmpty
            $Result.TestSampleContent.StartsWith('New-Item') | Should -BeTrue
            $Result.TestSampleContent    | Should -Match 'Registry::HKEY_CURRENT_USER'
        }

        It 'should create a new registry key using the following method: RegExeCommandLine' -Tag 'Technique', 'T1112' {
            # First, ensure that the key doesn't exist
            Remove-Item -Path "Registry::HKEY_CURRENT_USER\$RegistryKeyPath" -Force -ErrorAction Ignore

            $Result = Set-ATHRegistry -Method RegExeCommandLine -Hive HKCU -KeyPath $RegistryKeyPath -ErrorAction Stop
            
            $Result | Should -Not -BeNullOrEmpty

            $Result.TechniqueID          | Should -BeExactly $ExpectedTechniqueID
            $Result.TestSuccess          | Should -BeTrue
            $Result.Method               | Should -BeExactly 'RegExeCommandLine'
            $Result.SetKeyOnly           | Should -BeTrue
            $Result.KeyPath              | Should -BeExactly "HKEY_CURRENT_USER\$RegistryKeyPath"
            $Result.ValueName            | Should -BeNullOrEmpty
            $Result.ValueType            | Should -BeNullOrEmpty
            $Result.ValueContent         | Should -BeNullOrEmpty
            $Result.PreviousValueType    | Should -BeNullOrEmpty
            $Result.PreviousValueContent | Should -BeNullOrEmpty
            $Result.ProcessId            | Should -Not -BeNullOrEmpty
            $Result.ProcessPath          | Should -Not -BeNullOrEmpty
            $Result.ProcessCommandLine   | Should -Not -BeNullOrEmpty
            $Result.TestSampleContent    | Should -Not -BeNullOrEmpty
            $Result.TestSampleContent    | Should -BeExactly $Result.ProcessCommandLine
        }

        It 'should create a new registry key using the following method: WMI' -Tag 'Technique', 'T1112' {
            # First, ensure that the key doesn't exist
            Remove-Item -Path "Registry::HKEY_CURRENT_USER\$RegistryKeyPath" -Force -ErrorAction Ignore

            $Result = Set-ATHRegistry -Method WMI -Hive HKCU -KeyPath $RegistryKeyPath -ErrorAction Stop
            
            $Result | Should -Not -BeNullOrEmpty

            $Result.TechniqueID          | Should -BeExactly $ExpectedTechniqueID
            $Result.TestSuccess          | Should -BeTrue
            $Result.Method               | Should -BeExactly 'WMI'
            $Result.SetKeyOnly           | Should -BeTrue
            $Result.KeyPath              | Should -BeExactly "HKEY_CURRENT_USER\$RegistryKeyPath"
            $Result.ValueName            | Should -BeNullOrEmpty
            $Result.ValueType            | Should -BeNullOrEmpty
            $Result.ValueContent         | Should -BeNullOrEmpty
            $Result.PreviousValueType    | Should -BeNullOrEmpty
            $Result.PreviousValueContent | Should -BeNullOrEmpty
            $Result.ProcessId            | Should -BeNullOrEmpty
            $Result.ProcessPath          | Should -BeNullOrEmpty
            $Result.ProcessCommandLine   | Should -BeNullOrEmpty
            $Result.TestSampleContent    | Should -Not -BeNullOrEmpty
            $Result.TestSampleContent.StartsWith("Invoke-CimMethod -Namespace 'ROOT/default' -ClassName 'StdRegProv' -MethodName 'CreateKey'") | Should -BeTrue
        }

        It 'should force creation of an existing key with the -Force switch using the following method: PowerShell' -Tag 'Technique', 'T1112' {
            # First, ensure that the key doesn't exist
            Remove-Item -Path "Registry::HKEY_CURRENT_USER\$RegistryKeyPath" -Force -ErrorAction Ignore

            # Now, ensure that the key already exists
            $NewKey = New-Item -Path 'Registry::HKEY_CURRENT_USER\AtomicTestHarnesses' -Name 'T1112' -Force -ErrorAction Stop
            $NewKey | Should -Not -BeNullOrEmpty

            $Result = Set-ATHRegistry -Method PowerShell -Hive HKCU -KeyPath $RegistryKeyPath -Force -ErrorAction Stop
            
            $Result | Should -Not -BeNullOrEmpty

            $Result.TechniqueID          | Should -BeExactly $ExpectedTechniqueID
            $Result.TestSuccess          | Should -BeTrue
            $Result.Method               | Should -BeExactly 'PowerShell'
            $Result.SetKeyOnly           | Should -BeTrue
            $Result.KeyPath              | Should -BeExactly "HKEY_CURRENT_USER\$RegistryKeyPath"
            $Result.ValueName            | Should -BeNullOrEmpty
            $Result.ValueType            | Should -BeNullOrEmpty
            $Result.ValueContent         | Should -BeNullOrEmpty
            $Result.PreviousValueType    | Should -BeNullOrEmpty
            $Result.PreviousValueContent | Should -BeNullOrEmpty
            $Result.ProcessId            | Should -Be $PID
            $Result.ProcessPath          | Should -BeExactly ((Get-Process -Id $PID).MainModule.FileName)
            $Result.ProcessCommandLine   | Should -Not -BeNullOrEmpty
            $Result.TestSampleContent    | Should -Not -BeNullOrEmpty
            $Result.TestSampleContent.StartsWith('Remove-Item') | Should -BeTrue
            $Result.TestSampleContent    | Should -Match 'Registry::HKEY_CURRENT_USER'
        }

        It 'should force creation of an existing key with the -Force switch using the following method: RegExeCommandLine' -Tag 'Technique', 'T1112' {
            # First, ensure that the key doesn't exist
            Remove-Item -Path "Registry::HKEY_CURRENT_USER\$RegistryKeyPath" -Force -ErrorAction Ignore

            # Now, ensure that the key already exists
            $NewKey = New-Item -Path 'Registry::HKEY_CURRENT_USER\AtomicTestHarnesses' -Name 'T1112' -Force -ErrorAction Stop
            $NewKey | Should -Not -BeNullOrEmpty

            $Result = Set-ATHRegistry -Method RegExeCommandLine -Hive HKCU -KeyPath $RegistryKeyPath -Force -ErrorAction Stop
            
            $Result | Should -Not -BeNullOrEmpty

            $Result.TechniqueID          | Should -BeExactly $ExpectedTechniqueID
            $Result.TestSuccess          | Should -BeTrue
            $Result.Method               | Should -BeExactly 'RegExeCommandLine'
            $Result.SetKeyOnly           | Should -BeTrue
            $Result.KeyPath              | Should -BeExactly "HKEY_CURRENT_USER\$RegistryKeyPath"
            $Result.ValueName            | Should -BeNullOrEmpty
            $Result.ValueType            | Should -BeNullOrEmpty
            $Result.ValueContent         | Should -BeNullOrEmpty
            $Result.PreviousValueType    | Should -BeNullOrEmpty
            $Result.PreviousValueContent | Should -BeNullOrEmpty
            $Result.ProcessId            | Should -Not -BeNullOrEmpty
            $Result.ProcessPath          | Should -Not -BeNullOrEmpty
            $Result.ProcessCommandLine   | Should -Not -BeNullOrEmpty
            $Result.TestSampleContent    | Should -Not -BeNullOrEmpty
            $Result.TestSampleContent    | Should -BeExactly $Result.ProcessCommandLine
        }

        It 'should force creation of an existing key with the -Force switch using the following method: WMI' -Tag 'Technique', 'T1112' {
            # First, ensure that the key doesn't exist
            Remove-Item -Path "Registry::HKEY_CURRENT_USER\$RegistryKeyPath" -Force -ErrorAction Ignore

            # Now, ensure that the key already exists
            $NewKey = New-Item -Path 'Registry::HKEY_CURRENT_USER\AtomicTestHarnesses' -Name 'T1112' -Force -ErrorAction Stop
            $NewKey | Should -Not -BeNullOrEmpty

            $Result = Set-ATHRegistry -Method WMI -Hive HKCU -KeyPath $RegistryKeyPath -Force -ErrorAction Stop
            
            $Result | Should -Not -BeNullOrEmpty

            $Result.TechniqueID          | Should -BeExactly $ExpectedTechniqueID
            $Result.TestSuccess          | Should -BeTrue
            $Result.Method               | Should -BeExactly 'WMI'
            $Result.SetKeyOnly           | Should -BeTrue
            $Result.KeyPath              | Should -BeExactly "HKEY_CURRENT_USER\$RegistryKeyPath"
            $Result.ValueName            | Should -BeNullOrEmpty
            $Result.ValueType            | Should -BeNullOrEmpty
            $Result.ValueContent         | Should -BeNullOrEmpty
            $Result.PreviousValueType    | Should -BeNullOrEmpty
            $Result.PreviousValueContent | Should -BeNullOrEmpty
            $Result.ProcessId            | Should -BeNullOrEmpty
            $Result.ProcessPath          | Should -BeNullOrEmpty
            $Result.ProcessCommandLine   | Should -BeNullOrEmpty
            $Result.TestSampleContent    | Should -Not -BeNullOrEmpty
            $Result.TestSampleContent.StartsWith("Invoke-CimMethod -Namespace 'ROOT/default' -ClassName 'StdRegProv' -MethodName 'CreateKey'") | Should -BeTrue
        }

        It 'should mock creating a new registry key with the -OnlyOutputTestSample switch using the following method: PowerShell' -Tag 'Technique', 'T1112' {
            # First, ensure that the key doesn't exist
            Remove-Item -Path "Registry::HKEY_CURRENT_USER\$RegistryKeyPath" -Force -ErrorAction Ignore

            $Result = Set-ATHRegistry -Method PowerShell -Hive HKCU -KeyPath $RegistryKeyPath -OnlyOutputTestSample -ErrorAction Stop
            
            $Result | Should -Not -BeNullOrEmpty

            $Result.TechniqueID          | Should -BeExactly $ExpectedTechniqueID
            $Result.TestSuccess          | Should -BeNullOrEmpty
            $Result.Method               | Should -BeExactly 'PowerShell'
            $Result.SetKeyOnly           | Should -BeTrue
            $Result.KeyPath              | Should -BeExactly "HKEY_CURRENT_USER\$RegistryKeyPath"
            $Result.ValueName            | Should -BeNullOrEmpty
            $Result.ValueType            | Should -BeNullOrEmpty
            $Result.ValueContent         | Should -BeNullOrEmpty
            $Result.PreviousValueType    | Should -BeNullOrEmpty
            $Result.PreviousValueContent | Should -BeNullOrEmpty
            $Result.ProcessId            | Should -BeNullOrEmpty
            $Result.ProcessPath          | Should -BeNullOrEmpty
            $Result.ProcessCommandLine   | Should -BeNullOrEmpty
            $Result.TestSampleContent    | Should -Not -BeNullOrEmpty
            $Result.TestSampleContent.StartsWith('New-Item') | Should -BeTrue
            $Result.TestSampleContent    | Should -Match 'Registry::HKEY_CURRENT_USER'
        }

        It 'should mock creating a new registry key with the -OnlyOutputTestSample switch using the following method: RegExeCommandLine' -Tag 'Technique', 'T1112' {
            # First, ensure that the key doesn't exist
            Remove-Item -Path "Registry::HKEY_CURRENT_USER\$RegistryKeyPath" -Force -ErrorAction Ignore

            $Result = Set-ATHRegistry -Method RegExeCommandLine -Hive HKCU -KeyPath $RegistryKeyPath -OnlyOutputTestSample -ErrorAction Stop
            
            $Result | Should -Not -BeNullOrEmpty

            $Result.TechniqueID          | Should -BeExactly $ExpectedTechniqueID
            $Result.TestSuccess          | Should -BeNullOrEmpty
            $Result.Method               | Should -BeExactly 'RegExeCommandLine'
            $Result.SetKeyOnly           | Should -BeTrue
            $Result.KeyPath              | Should -BeExactly "HKEY_CURRENT_USER\$RegistryKeyPath"
            $Result.ValueName            | Should -BeNullOrEmpty
            $Result.ValueType            | Should -BeNullOrEmpty
            $Result.ValueContent         | Should -BeNullOrEmpty
            $Result.PreviousValueType    | Should -BeNullOrEmpty
            $Result.PreviousValueContent | Should -BeNullOrEmpty
            $Result.ProcessId            | Should -BeNullOrEmpty
            $Result.ProcessPath          | Should -BeNullOrEmpty
            $Result.ProcessCommandLine   | Should -BeNullOrEmpty
            $Result.TestSampleContent    | Should -Not -BeNullOrEmpty
        }

        It 'should mock creating a new registry key with the -OnlyOutputTestSample switch using the following method: WMI' -Tag 'Technique', 'T1112' {
            # First, ensure that the key doesn't exist
            Remove-Item -Path "Registry::HKEY_CURRENT_USER\$RegistryKeyPath" -Force -ErrorAction Ignore

            $Result = Set-ATHRegistry -Method WMI -Hive HKCU -KeyPath $RegistryKeyPath -OnlyOutputTestSample -ErrorAction Stop
            
            $Result | Should -Not -BeNullOrEmpty

            $Result.TechniqueID          | Should -BeExactly $ExpectedTechniqueID
            $Result.TestSuccess          | Should -BeNullOrEmpty
            $Result.Method               | Should -BeExactly 'WMI'
            $Result.SetKeyOnly           | Should -BeTrue
            $Result.KeyPath              | Should -BeExactly "HKEY_CURRENT_USER\$RegistryKeyPath"
            $Result.ValueName            | Should -BeNullOrEmpty
            $Result.ValueType            | Should -BeNullOrEmpty
            $Result.ValueContent         | Should -BeNullOrEmpty
            $Result.PreviousValueType    | Should -BeNullOrEmpty
            $Result.PreviousValueContent | Should -BeNullOrEmpty
            $Result.ProcessId            | Should -BeNullOrEmpty
            $Result.ProcessPath          | Should -BeNullOrEmpty
            $Result.ProcessCommandLine   | Should -BeNullOrEmpty
            $Result.TestSampleContent    | Should -Not -BeNullOrEmpty
            $Result.TestSampleContent.StartsWith("Invoke-CimMethod -Namespace 'ROOT/default' -ClassName 'StdRegProv' -MethodName 'CreateKey'") | Should -BeTrue
        }

        It 'should mock creation of an existing key with the -Force switch using the following method: PowerShell' -Tag 'Technique', 'T1112' {
            # First, ensure that the key doesn't exist
            Remove-Item -Path "Registry::HKEY_CURRENT_USER\$RegistryKeyPath" -Force -ErrorAction Ignore

            # Now, ensure that the key already exists
            $NewKey = New-Item -Path 'Registry::HKEY_CURRENT_USER\AtomicTestHarnesses' -Name 'T1112' -Force -ErrorAction Stop
            $NewKey | Should -Not -BeNullOrEmpty

            $Result = Set-ATHRegistry -Method PowerShell -Hive HKCU -KeyPath $RegistryKeyPath -Force -OnlyOutputTestSample -ErrorAction Stop
            
            $Result | Should -Not -BeNullOrEmpty

            $Result.TechniqueID          | Should -BeExactly $ExpectedTechniqueID
            $Result.TestSuccess          | Should -BeNullOrEmpty
            $Result.Method               | Should -BeExactly 'PowerShell'
            $Result.SetKeyOnly           | Should -BeTrue
            $Result.KeyPath              | Should -BeExactly "HKEY_CURRENT_USER\$RegistryKeyPath"
            $Result.ValueName            | Should -BeNullOrEmpty
            $Result.ValueType            | Should -BeNullOrEmpty
            $Result.ValueContent         | Should -BeNullOrEmpty
            $Result.PreviousValueType    | Should -BeNullOrEmpty
            $Result.PreviousValueContent | Should -BeNullOrEmpty
            $Result.ProcessId            | Should -BeNullOrEmpty
            $Result.ProcessPath          | Should -BeNullOrEmpty
            $Result.ProcessCommandLine   | Should -BeNullOrEmpty
            $Result.TestSampleContent    | Should -Not -BeNullOrEmpty
            $Result.TestSampleContent.StartsWith('Remove-Item') | Should -BeTrue
            $Result.TestSampleContent    | Should -Match 'Registry::HKEY_CURRENT_USER'
        }

        It 'should mock creation of an existing key with the -Force switch using the following method: RegExeCommandLine' -Tag 'Technique', 'T1112' {
            # First, ensure that the key doesn't exist
            Remove-Item -Path "Registry::HKEY_CURRENT_USER\$RegistryKeyPath" -Force -ErrorAction Ignore

            # Now, ensure that the key already exists
            $NewKey = New-Item -Path 'Registry::HKEY_CURRENT_USER\AtomicTestHarnesses' -Name 'T1112' -Force -ErrorAction Stop
            $NewKey | Should -Not -BeNullOrEmpty

            $Result = Set-ATHRegistry -Method RegExeCommandLine -Hive HKCU -KeyPath $RegistryKeyPath -Force -OnlyOutputTestSample -ErrorAction Stop
            
            $Result | Should -Not -BeNullOrEmpty

            $Result.TechniqueID          | Should -BeExactly $ExpectedTechniqueID
            $Result.TestSuccess          | Should -BeNullOrEmpty
            $Result.Method               | Should -BeExactly 'RegExeCommandLine'
            $Result.SetKeyOnly           | Should -BeTrue
            $Result.KeyPath              | Should -BeExactly "HKEY_CURRENT_USER\$RegistryKeyPath"
            $Result.ValueName            | Should -BeNullOrEmpty
            $Result.ValueType            | Should -BeNullOrEmpty
            $Result.ValueContent         | Should -BeNullOrEmpty
            $Result.PreviousValueType    | Should -BeNullOrEmpty
            $Result.PreviousValueContent | Should -BeNullOrEmpty
            $Result.ProcessId            | Should -BeNullOrEmpty
            $Result.ProcessPath          | Should -BeNullOrEmpty
            $Result.ProcessCommandLine   | Should -BeNullOrEmpty
            $Result.TestSampleContent    | Should -Not -BeNullOrEmpty
        }

        It 'should mock creation of an existing key with the -Force switch using the following method: WMI' -Tag 'Technique', 'T1112' {
            # First, ensure that the key doesn't exist
            Remove-Item -Path "Registry::HKEY_CURRENT_USER\$RegistryKeyPath" -Force -ErrorAction Ignore

            # Now, ensure that the key already exists
            $NewKey = New-Item -Path 'Registry::HKEY_CURRENT_USER\AtomicTestHarnesses' -Name 'T1112' -Force -ErrorAction Stop
            $NewKey | Should -Not -BeNullOrEmpty

            $Result = Set-ATHRegistry -Method WMI -Hive HKCU -KeyPath $RegistryKeyPath -Force -OnlyOutputTestSample -ErrorAction Stop
            
            $Result | Should -Not -BeNullOrEmpty

            $Result.TechniqueID          | Should -BeExactly $ExpectedTechniqueID
            $Result.TestSuccess          | Should -BeNullOrEmpty
            $Result.Method               | Should -BeExactly 'WMI'
            $Result.SetKeyOnly           | Should -BeTrue
            $Result.KeyPath              | Should -BeExactly "HKEY_CURRENT_USER\$RegistryKeyPath"
            $Result.ValueName            | Should -BeNullOrEmpty
            $Result.ValueType            | Should -BeNullOrEmpty
            $Result.ValueContent         | Should -BeNullOrEmpty
            $Result.PreviousValueType    | Should -BeNullOrEmpty
            $Result.PreviousValueContent | Should -BeNullOrEmpty
            $Result.ProcessId            | Should -BeNullOrEmpty
            $Result.ProcessPath          | Should -BeNullOrEmpty
            $Result.ProcessCommandLine   | Should -BeNullOrEmpty
            $Result.TestSampleContent    | Should -Not -BeNullOrEmpty
            $Result.TestSampleContent.StartsWith("Invoke-CimMethod -Namespace 'ROOT/default' -ClassName 'StdRegProv' -MethodName 'CreateKey'") | Should -BeTrue
        }

        It 'should create a registry value from a key that does not currently exist using the following method: <Method>' -Tag 'Technique', 'T1112' {
            # First, ensure that the key doesn't exist
            Remove-Item -Path "Registry::HKEY_CURRENT_USER\$RegistryKeyPath" -Force -ErrorAction Ignore

            $Result = Set-ATHRegistry -Method $Method -Hive HKCU -KeyPath $RegistryKeyPath -ValueName $ValueName -ValueString 'Hello' -ErrorAction Stop

            $Result | Should -Not -BeNullOrEmpty

            $Result.TechniqueID          | Should -BeExactly $ExpectedTechniqueID
            $Result.TestSuccess          | Should -BeTrue
            $Result.Method               | Should -BeExactly $Method
            $Result.SetKeyOnly           | Should -BeFalse
            $Result.KeyPath              | Should -BeExactly "HKEY_CURRENT_USER\$RegistryKeyPath"
            $Result.ValueName            | Should -BeExactly $ValueName
            $Result.ValueType            | Should -BeExactly 'String'
            $Result.ValueContent         | Should -BeExactly 'Hello'
            $Result.PreviousValueType    | Should -BeNullOrEmpty
            $Result.PreviousValueContent | Should -BeNullOrEmpty
            $Result.TestSampleContent    | Should -Not -BeNullOrEmpty
        } -TestCases @(
            @{ Method = 'PowerShell' },
            @{ Method = 'RegExeCommandLine' },
            @{ Method = 'WMI' },
            @{ Method = 'VBScriptWscriptShellRegWrite' },
            @{ Method = 'JScriptWscriptShellRegWrite' }
        )

        It 'should overwrite an existing registry value using the following method: <Method>' -Tag 'Technique', 'T1112' {
            # First, ensure that the key doesn't exist
            Remove-Item -Path "Registry::HKEY_CURRENT_USER\$RegistryKeyPath" -Force -ErrorAction Ignore

            # Ensure that the key and the value exist prior to the overwrite
            $null = New-Item -Path 'Registry::HKEY_CURRENT_USER\AtomicTestHarnesses' -Name 'T1112' -ErrorAction Stop
            Set-ItemProperty -Path 'Registry::HKEY_CURRENT_USER\AtomicTestHarnesses\T1112' -Name $ValueName -Type String -Value 'Hello' -ErrorAction Stop

            $Result = Set-ATHRegistry -Method $Method -Hive HKCU -KeyPath $RegistryKeyPath -ValueName $ValueName -ValueDword 4 -Force -ErrorAction Stop

            $Result | Should -Not -BeNullOrEmpty

            $Result.TechniqueID          | Should -BeExactly $ExpectedTechniqueID
            $Result.TestSuccess          | Should -BeTrue
            $Result.Method               | Should -BeExactly $Method
            $Result.SetKeyOnly           | Should -BeFalse
            $Result.KeyPath              | Should -BeExactly "HKEY_CURRENT_USER\$RegistryKeyPath"
            $Result.ValueName            | Should -BeExactly $ValueName
            $Result.ValueType            | Should -BeExactly 'DWord'
            $Result.ValueContent         | Should -Be 4
            $Result.PreviousValueType    | Should -BeExactly 'String'
            $Result.PreviousValueContent | Should -BeExactly 'Hello'
            $Result.TestSampleContent    | Should -Not -BeNullOrEmpty
        } -TestCases @(
            @{ Method = 'PowerShell' },
            @{ Method = 'RegExeCommandLine' },
            @{ Method = 'WMI' },
            @{ Method = 'VBScriptWscriptShellRegWrite' },
            @{ Method = 'JScriptWscriptShellRegWrite' }
        )

        It 'should mock the creation of a new value with the -OnlyOutputTestSample switch using the following method: <Method>' -Tag 'Technique', 'T1112' {
            # First, ensure that the key doesn't exist
            Remove-Item -Path "Registry::HKEY_CURRENT_USER\$RegistryKeyPath" -Force -ErrorAction Ignore

            $Result = Set-ATHRegistry -Method $Method -Hive HKCU -KeyPath $RegistryKeyPath -ValueName $ValueName -ValueDword 4 -OnlyOutputTestSample -ErrorAction Stop

            $Result | Should -Not -BeNullOrEmpty

            $Result.TechniqueID          | Should -BeExactly $ExpectedTechniqueID
            $Result.TestSuccess          | Should -BeNullOrEmpty
            $Result.Method               | Should -BeExactly $Method
            $Result.SetKeyOnly           | Should -BeFalse
            $Result.KeyPath              | Should -BeExactly "HKEY_CURRENT_USER\$RegistryKeyPath"
            $Result.ValueName            | Should -BeExactly $ValueName
            $Result.ValueType            | Should -BeExactly 'DWord'
            $Result.ValueContent         | Should -Be 4
            $Result.PreviousValueType    | Should -BeNullOrEmpty
            $Result.PreviousValueContent | Should -BeNullOrEmpty
            $Result.ProcessId            | Should -BeNullOrEmpty
            $Result.ProcessPath          | Should -BeNullOrEmpty
            $Result.ProcessCommandLine   | Should -BeNullOrEmpty
            $Result.TestSampleContent    | Should -Not -BeNullOrEmpty
        } -TestCases @(
            @{ Method = 'PowerShell' },
            @{ Method = 'RegExeCommandLine' },
            @{ Method = 'WMI' },
            @{ Method = 'VBScriptWscriptShellRegWrite' },
            @{ Method = 'JScriptWscriptShellRegWrite' }
        )

        It 'should mock the overwriting of an exising value with the -OnlyOutputTestSample switch using the following method: <Method>' -Tag 'Technique', 'T1112' {
            # First, ensure that the key doesn't exist
            Remove-Item -Path "Registry::HKEY_CURRENT_USER\$RegistryKeyPath" -Force -ErrorAction Ignore

            # Ensure that the key and the value exist prior to the overwrite
            $null = New-Item -Path 'Registry::HKEY_CURRENT_USER\AtomicTestHarnesses' -Name 'T1112' -ErrorAction Stop
            Set-ItemProperty -Path 'Registry::HKEY_CURRENT_USER\AtomicTestHarnesses\T1112' -Name $ValueName -Type String -Value 'Hello' -ErrorAction Stop

            $Result = Set-ATHRegistry -Method $Method -Hive HKCU -KeyPath $RegistryKeyPath -ValueName $ValueName -ValueDword 4 -OnlyOutputTestSample -ErrorAction Stop

            $Result | Should -Not -BeNullOrEmpty

            $Result.TechniqueID          | Should -BeExactly $ExpectedTechniqueID
            $Result.TestSuccess          | Should -BeNullOrEmpty
            $Result.Method               | Should -BeExactly $Method
            $Result.SetKeyOnly           | Should -BeFalse
            $Result.KeyPath              | Should -BeExactly "HKEY_CURRENT_USER\$RegistryKeyPath"
            $Result.ValueName            | Should -BeExactly $ValueName
            $Result.ValueType            | Should -BeExactly 'DWord'
            $Result.ValueContent         | Should -Be 4
            $Result.PreviousValueType    | Should -BeExactly 'String'
            $Result.PreviousValueContent | Should -BeExactly 'Hello'
            $Result.ProcessId            | Should -BeNullOrEmpty
            $Result.ProcessPath          | Should -BeNullOrEmpty
            $Result.ProcessCommandLine   | Should -BeNullOrEmpty
            $Result.TestSampleContent    | Should -Not -BeNullOrEmpty
        } -TestCases @(
            @{ Method = 'PowerShell' },
            @{ Method = 'RegExeCommandLine' },
            @{ Method = 'WMI' },
            @{ Method = 'VBScriptWscriptShellRegWrite' },
            @{ Method = 'JScriptWscriptShellRegWrite' }
        )

        It 'should set a String registry value using the following method: <Method>' -Tag 'Technique', 'T1112' {
            # First, ensure that the key doesn't exist
            Remove-Item -Path "Registry::HKEY_CURRENT_USER\$RegistryKeyPath" -Force -ErrorAction Ignore

            $Result = Set-ATHRegistry -Method $Method -Hive HKCU -KeyPath $RegistryKeyPath -ValueName $ValueName -ValueString 'Hello' -ErrorAction Stop

            $Result | Should -Not -BeNullOrEmpty

            $Result.TechniqueID          | Should -BeExactly $ExpectedTechniqueID
            $Result.TestSuccess          | Should -BeTrue
            $Result.Method               | Should -BeExactly $Method
            $Result.SetKeyOnly           | Should -BeFalse
            $Result.KeyPath              | Should -BeExactly "HKEY_CURRENT_USER\$RegistryKeyPath"
            $Result.ValueName            | Should -BeExactly $ValueName
            $Result.ValueType            | Should -BeExactly 'String'
            $Result.ValueContent         | Should -Be 'Hello'
            $Result.PreviousValueType    | Should -BeNullOrEmpty
            $Result.PreviousValueContent | Should -BeNullOrEmpty

            if ($Method -eq 'WMI') {
                $Result.ProcessId            | Should -BeNullOrEmpty
                $Result.ProcessPath          | Should -BeNullOrEmpty
                $Result.ProcessCommandLine   | Should -BeNullOrEmpty
            } else {
                $Result.ProcessId            | Should -Not -BeNullOrEmpty
                $Result.ProcessPath          | Should -Not -BeNullOrEmpty
                $Result.ProcessCommandLine   | Should -Not -BeNullOrEmpty
            }
            
            $Result.TestSampleContent    | Should -Not -BeNullOrEmpty
        } -TestCases @(
            @{ Method = 'PowerShell' },
            @{ Method = 'RegExeCommandLine' },
            @{ Method = 'WMI' },
            @{ Method = 'VBScriptWscriptShellRegWrite' },
            @{ Method = 'JScriptWscriptShellRegWrite' }
        )

        It 'should set a ExpandString registry value using the following method: <Method>' -Tag 'Technique', 'T1112' {
            # First, ensure that the key doesn't exist
            Remove-Item -Path "Registry::HKEY_CURRENT_USER\$RegistryKeyPath" -Force -ErrorAction Ignore

            $Result = Set-ATHRegistry -Method $Method -Hive HKCU -KeyPath $RegistryKeyPath -ValueName $ValueName -ValueExpandString '%windir%' -ErrorAction Stop

            $Result | Should -Not -BeNullOrEmpty

            $Result.TechniqueID          | Should -BeExactly $ExpectedTechniqueID
            $Result.TestSuccess          | Should -BeTrue
            $Result.Method               | Should -BeExactly $Method
            $Result.SetKeyOnly           | Should -BeFalse
            $Result.KeyPath              | Should -BeExactly "HKEY_CURRENT_USER\$RegistryKeyPath"
            $Result.ValueName            | Should -BeExactly $ValueName
            $Result.ValueType            | Should -BeExactly 'ExpandString'
            $Result.ValueContent         | Should -Be '%windir%'
            $Result.PreviousValueType    | Should -BeNullOrEmpty
            $Result.PreviousValueContent | Should -BeNullOrEmpty

            if ($Method -eq 'WMI') {
                $Result.ProcessId            | Should -BeNullOrEmpty
                $Result.ProcessPath          | Should -BeNullOrEmpty
                $Result.ProcessCommandLine   | Should -BeNullOrEmpty
            } else {
                $Result.ProcessId            | Should -Not -BeNullOrEmpty
                $Result.ProcessPath          | Should -Not -BeNullOrEmpty
                $Result.ProcessCommandLine   | Should -Not -BeNullOrEmpty
            }
            
            $Result.TestSampleContent    | Should -Not -BeNullOrEmpty
        } -TestCases @(
            @{ Method = 'PowerShell' },
            @{ Method = 'RegExeCommandLine' },
            @{ Method = 'WMI' },
            @{ Method = 'VBScriptWscriptShellRegWrite' },
            @{ Method = 'JScriptWscriptShellRegWrite' }
        )

        It 'should set a MultiString registry value using the following method: <Method>' -Tag 'Technique', 'T1112' {
            # First, ensure that the key doesn't exist
            Remove-Item -Path "Registry::HKEY_CURRENT_USER\$RegistryKeyPath" -Force -ErrorAction Ignore

            $Result = Set-ATHRegistry -Method $Method -Hive HKCU -KeyPath $RegistryKeyPath -ValueName $ValueName -ValueMultiString @('Hello', 'World') -ErrorAction Stop

            $Result | Should -Not -BeNullOrEmpty

            $Result.TechniqueID          | Should -BeExactly $ExpectedTechniqueID
            $Result.TestSuccess          | Should -BeTrue
            $Result.Method               | Should -BeExactly $Method
            $Result.SetKeyOnly           | Should -BeFalse
            $Result.KeyPath              | Should -BeExactly "HKEY_CURRENT_USER\$RegistryKeyPath"
            $Result.ValueName            | Should -BeExactly $ValueName
            $Result.ValueType            | Should -BeExactly 'MultiString'
            $Result.ValueContent -is ([String[]]) | Should -BeTrue
            $Result.ValueContent.Count   | Should -Be 2
            $Result.ValueContent[0]      | Should -Be 'Hello'
            $Result.ValueContent[1]      | Should -Be 'World'
            $Result.PreviousValueType    | Should -BeNullOrEmpty
            $Result.PreviousValueContent | Should -BeNullOrEmpty

            if ($Method -eq 'WMI') {
                $Result.ProcessId            | Should -BeNullOrEmpty
                $Result.ProcessPath          | Should -BeNullOrEmpty
                $Result.ProcessCommandLine   | Should -BeNullOrEmpty
            } else {
                $Result.ProcessId            | Should -Not -BeNullOrEmpty
                $Result.ProcessPath          | Should -Not -BeNullOrEmpty
                $Result.ProcessCommandLine   | Should -Not -BeNullOrEmpty
            }
            
            $Result.TestSampleContent    | Should -Not -BeNullOrEmpty
        } -TestCases @(
            @{ Method = 'PowerShell' },
            @{ Method = 'RegExeCommandLine' },
            @{ Method = 'WMI' }
        )

        It 'should set a Binary registry value using the following method: <Method>' -Tag 'Technique', 'T1112' {
            # First, ensure that the key doesn't exist
            Remove-Item -Path "Registry::HKEY_CURRENT_USER\$RegistryKeyPath" -Force -ErrorAction Ignore

            $Result = Set-ATHRegistry -Method $Method -Hive HKCU -KeyPath $RegistryKeyPath -ValueName $ValueName -ValueBinary @(1,2,3) -ErrorAction Stop

            $Result | Should -Not -BeNullOrEmpty

            $Result.TechniqueID          | Should -BeExactly $ExpectedTechniqueID
            $Result.TestSuccess          | Should -BeTrue
            $Result.Method               | Should -BeExactly $Method
            $Result.SetKeyOnly           | Should -BeFalse
            $Result.KeyPath              | Should -BeExactly "HKEY_CURRENT_USER\$RegistryKeyPath"
            $Result.ValueName            | Should -BeExactly $ValueName
            $Result.ValueType            | Should -BeExactly 'Binary'
            $Result.ValueContent -is ([Byte[]]) | Should -BeTrue
            $Result.ValueContent.Count   | Should -Be 3
            $Result.ValueContent[0]      | Should -Be 1
            $Result.ValueContent[1]      | Should -Be 2
            $Result.ValueContent[2]      | Should -Be 3
            $Result.PreviousValueType    | Should -BeNullOrEmpty
            $Result.PreviousValueContent | Should -BeNullOrEmpty

            if ($Method -eq 'WMI') {
                $Result.ProcessId            | Should -BeNullOrEmpty
                $Result.ProcessPath          | Should -BeNullOrEmpty
                $Result.ProcessCommandLine   | Should -BeNullOrEmpty
            } else {
                $Result.ProcessId            | Should -Not -BeNullOrEmpty
                $Result.ProcessPath          | Should -Not -BeNullOrEmpty
                $Result.ProcessCommandLine   | Should -Not -BeNullOrEmpty
            }
            
            $Result.TestSampleContent    | Should -Not -BeNullOrEmpty
        } -TestCases @(
            @{ Method = 'PowerShell' },
            @{ Method = 'RegExeCommandLine' },
            @{ Method = 'WMI' }
        )

        It 'should set a DWord registry value using the following method: <Method>' -Tag 'Technique', 'T1112' {
            # First, ensure that the key doesn't exist
            Remove-Item -Path "Registry::HKEY_CURRENT_USER\$RegistryKeyPath" -Force -ErrorAction Ignore

            $Result = Set-ATHRegistry -Method $Method -Hive HKCU -KeyPath $RegistryKeyPath -ValueName $ValueName -ValueDword 4 -ErrorAction Stop

            $Result | Should -Not -BeNullOrEmpty

            $Result.TechniqueID          | Should -BeExactly $ExpectedTechniqueID
            $Result.TestSuccess          | Should -BeTrue
            $Result.Method               | Should -BeExactly $Method
            $Result.SetKeyOnly           | Should -BeFalse
            $Result.KeyPath              | Should -BeExactly "HKEY_CURRENT_USER\$RegistryKeyPath"
            $Result.ValueName            | Should -BeExactly $ValueName
            $Result.ValueType            | Should -BeExactly 'DWord'
            $Result.ValueContent         | Should -Be 4
            $Result.PreviousValueType    | Should -BeNullOrEmpty
            $Result.PreviousValueContent | Should -BeNullOrEmpty

            if ($Method -eq 'WMI') {
                $Result.ProcessId            | Should -BeNullOrEmpty
                $Result.ProcessPath          | Should -BeNullOrEmpty
                $Result.ProcessCommandLine   | Should -BeNullOrEmpty
            } else {
                $Result.ProcessId            | Should -Not -BeNullOrEmpty
                $Result.ProcessPath          | Should -Not -BeNullOrEmpty
                $Result.ProcessCommandLine   | Should -Not -BeNullOrEmpty
            }
            
            $Result.TestSampleContent    | Should -Not -BeNullOrEmpty
        } -TestCases @(
            @{ Method = 'PowerShell' },
            @{ Method = 'RegExeCommandLine' },
            @{ Method = 'WMI' },
            @{ Method = 'VBScriptWscriptShellRegWrite' },
            @{ Method = 'JScriptWscriptShellRegWrite' }
        )

        It 'should set a QWord registry value using the following method: <Method>' -Tag 'Technique', 'T1112' {
            # First, ensure that the key doesn't exist
            Remove-Item -Path "Registry::HKEY_CURRENT_USER\$RegistryKeyPath" -Force -ErrorAction Ignore

            $Result = Set-ATHRegistry -Method $Method -Hive HKCU -KeyPath $RegistryKeyPath -ValueName $ValueName -ValueQword 4 -ErrorAction Stop

            $Result | Should -Not -BeNullOrEmpty

            $Result.TechniqueID          | Should -BeExactly $ExpectedTechniqueID
            $Result.TestSuccess          | Should -BeTrue
            $Result.Method               | Should -BeExactly $Method
            $Result.SetKeyOnly           | Should -BeFalse
            $Result.KeyPath              | Should -BeExactly "HKEY_CURRENT_USER\$RegistryKeyPath"
            $Result.ValueName            | Should -BeExactly $ValueName
            $Result.ValueType            | Should -BeExactly 'QWord'
            $Result.ValueContent         | Should -Be 4
            $Result.PreviousValueType    | Should -BeNullOrEmpty
            $Result.PreviousValueContent | Should -BeNullOrEmpty

            if ($Method -eq 'WMI') {
                $Result.ProcessId            | Should -BeNullOrEmpty
                $Result.ProcessPath          | Should -BeNullOrEmpty
                $Result.ProcessCommandLine   | Should -BeNullOrEmpty
            } else {
                $Result.ProcessId            | Should -Not -BeNullOrEmpty
                $Result.ProcessPath          | Should -Not -BeNullOrEmpty
                $Result.ProcessCommandLine   | Should -Not -BeNullOrEmpty
            }
            
            $Result.TestSampleContent    | Should -Not -BeNullOrEmpty
        } -TestCases @(
            @{ Method = 'PowerShell' },
            @{ Method = 'RegExeCommandLine' },
            @{ Method = 'WMI' }
        )

        It 'should set a String registry value for an existing registry value using the following method: <Method>' -Tag 'Technique', 'T1112' {
            # First, ensure that the key doesn't exist
            Remove-Item -Path "Registry::HKEY_CURRENT_USER\$RegistryKeyPath" -Force -ErrorAction Ignore

            # Ensure that the key and the value exist prior to the overwrite
            $null = New-Item -Path 'Registry::HKEY_CURRENT_USER\AtomicTestHarnesses' -Name 'T1112' -ErrorAction Stop
            Set-ItemProperty -Path 'Registry::HKEY_CURRENT_USER\AtomicTestHarnesses\T1112' -Name $ValueName -Type Dword -Value 4 -ErrorAction Stop

            $Result = Set-ATHRegistry -Method $Method -Hive HKCU -KeyPath $RegistryKeyPath -ValueName $ValueName -ValueString 'Hello' -Force -ErrorAction Stop

            $Result | Should -Not -BeNullOrEmpty

            $Result.TechniqueID          | Should -BeExactly $ExpectedTechniqueID
            $Result.TestSuccess          | Should -BeTrue
            $Result.Method               | Should -BeExactly $Method
            $Result.SetKeyOnly           | Should -BeFalse
            $Result.KeyPath              | Should -BeExactly "HKEY_CURRENT_USER\$RegistryKeyPath"
            $Result.ValueName            | Should -BeExactly $ValueName
            $Result.ValueType            | Should -BeExactly 'String'
            $Result.ValueContent         | Should -BeExactly 'Hello'
            $Result.PreviousValueType    | Should -BeExactly 'DWord'
            $Result.PreviousValueContent | Should -Be 4

            if ($Method -eq 'WMI') {
                $Result.ProcessId            | Should -BeNullOrEmpty
                $Result.ProcessPath          | Should -BeNullOrEmpty
                $Result.ProcessCommandLine   | Should -BeNullOrEmpty
            } else {
                $Result.ProcessId            | Should -Not -BeNullOrEmpty
                $Result.ProcessPath          | Should -Not -BeNullOrEmpty
                $Result.ProcessCommandLine   | Should -Not -BeNullOrEmpty
            }
            
            $Result.TestSampleContent    | Should -Not -BeNullOrEmpty
        } -TestCases @(
            @{ Method = 'PowerShell' },
            @{ Method = 'RegExeCommandLine' },
            @{ Method = 'WMI' },
            @{ Method = 'VBScriptWscriptShellRegWrite' },
            @{ Method = 'JScriptWscriptShellRegWrite' }
        )

        It 'should set a ExpandString registry value for an existing registry value using the following method: <Method>' -Tag 'Technique', 'T1112' {
            # First, ensure that the key doesn't exist
            Remove-Item -Path "Registry::HKEY_CURRENT_USER\$RegistryKeyPath" -Force -ErrorAction Ignore

            # Ensure that the key and the value exist prior to the overwrite
            $null = New-Item -Path 'Registry::HKEY_CURRENT_USER\AtomicTestHarnesses' -Name 'T1112' -ErrorAction Stop
            Set-ItemProperty -Path 'Registry::HKEY_CURRENT_USER\AtomicTestHarnesses\T1112' -Name $ValueName -Type String -Value 'Hello' -ErrorAction Stop

            $Result = Set-ATHRegistry -Method $Method -Hive HKCU -KeyPath $RegistryKeyPath -ValueName $ValueName -ValueExpandString '%windir%' -Force -ErrorAction Stop

            $Result | Should -Not -BeNullOrEmpty

            $Result.TechniqueID          | Should -BeExactly $ExpectedTechniqueID
            $Result.TestSuccess          | Should -BeTrue
            $Result.Method               | Should -BeExactly $Method
            $Result.SetKeyOnly           | Should -BeFalse
            $Result.KeyPath              | Should -BeExactly "HKEY_CURRENT_USER\$RegistryKeyPath"
            $Result.ValueName            | Should -BeExactly $ValueName
            $Result.ValueType            | Should -BeExactly 'ExpandString'
            $Result.ValueContent         | Should -Be '%windir%'
            $Result.PreviousValueType    | Should -BeExactly 'String'
            $Result.PreviousValueContent | Should -BeExactly 'Hello'

            if ($Method -eq 'WMI') {
                $Result.ProcessId            | Should -BeNullOrEmpty
                $Result.ProcessPath          | Should -BeNullOrEmpty
                $Result.ProcessCommandLine   | Should -BeNullOrEmpty
            } else {
                $Result.ProcessId            | Should -Not -BeNullOrEmpty
                $Result.ProcessPath          | Should -Not -BeNullOrEmpty
                $Result.ProcessCommandLine   | Should -Not -BeNullOrEmpty
            }
            
            $Result.TestSampleContent    | Should -Not -BeNullOrEmpty
        } -TestCases @(
            @{ Method = 'PowerShell' },
            @{ Method = 'RegExeCommandLine' },
            @{ Method = 'WMI' },
            @{ Method = 'VBScriptWscriptShellRegWrite' },
            @{ Method = 'JScriptWscriptShellRegWrite' }
        )

        It 'should set a MultiString registry value for an existing registry value using the following method: <Method>' -Tag 'Technique', 'T1112' {
            # First, ensure that the key doesn't exist
            Remove-Item -Path "Registry::HKEY_CURRENT_USER\$RegistryKeyPath" -Force -ErrorAction Ignore

            # Ensure that the key and the value exist prior to the overwrite
            $null = New-Item -Path 'Registry::HKEY_CURRENT_USER\AtomicTestHarnesses' -Name 'T1112' -ErrorAction Stop
            Set-ItemProperty -Path 'Registry::HKEY_CURRENT_USER\AtomicTestHarnesses\T1112' -Name $ValueName -Type String -Value 'Hello' -ErrorAction Stop

            $Result = Set-ATHRegistry -Method $Method -Hive HKCU -KeyPath $RegistryKeyPath -ValueName $ValueName -ValueMultiString @('Hello', 'World') -Force -ErrorAction Stop

            $Result | Should -Not -BeNullOrEmpty

            $Result.TechniqueID          | Should -BeExactly $ExpectedTechniqueID
            $Result.TestSuccess          | Should -BeTrue
            $Result.Method               | Should -BeExactly $Method
            $Result.SetKeyOnly           | Should -BeFalse
            $Result.KeyPath              | Should -BeExactly "HKEY_CURRENT_USER\$RegistryKeyPath"
            $Result.ValueName            | Should -BeExactly $ValueName
            $Result.ValueType            | Should -BeExactly 'MultiString'
            $Result.ValueContent -is ([String[]]) | Should -BeTrue
            $Result.ValueContent.Count   | Should -Be 2
            $Result.ValueContent[0]      | Should -Be 'Hello'
            $Result.ValueContent[1]      | Should -Be 'World'
            $Result.PreviousValueType    | Should -BeExactly 'String'
            $Result.PreviousValueContent | Should -BeExactly 'Hello'

            if ($Method -eq 'WMI') {
                $Result.ProcessId            | Should -BeNullOrEmpty
                $Result.ProcessPath          | Should -BeNullOrEmpty
                $Result.ProcessCommandLine   | Should -BeNullOrEmpty
            } else {
                $Result.ProcessId            | Should -Not -BeNullOrEmpty
                $Result.ProcessPath          | Should -Not -BeNullOrEmpty
                $Result.ProcessCommandLine   | Should -Not -BeNullOrEmpty
            }
            
            $Result.TestSampleContent    | Should -Not -BeNullOrEmpty
        } -TestCases @(
            @{ Method = 'PowerShell' },
            @{ Method = 'RegExeCommandLine' },
            @{ Method = 'WMI' }
        )

        It 'should set a Binary registry value for an existing registry value using the following method: <Method>' -Tag 'Technique', 'T1112' {
            # First, ensure that the key doesn't exist
            Remove-Item -Path "Registry::HKEY_CURRENT_USER\$RegistryKeyPath" -Force -ErrorAction Ignore

            # Ensure that the key and the value exist prior to the overwrite
            $null = New-Item -Path 'Registry::HKEY_CURRENT_USER\AtomicTestHarnesses' -Name 'T1112' -ErrorAction Stop
            Set-ItemProperty -Path 'Registry::HKEY_CURRENT_USER\AtomicTestHarnesses\T1112' -Name $ValueName -Type String -Value 'Hello' -ErrorAction Stop

            $Result = Set-ATHRegistry -Method $Method -Hive HKCU -KeyPath $RegistryKeyPath -ValueName $ValueName -ValueBinary @(1,2,3) -Force -ErrorAction Stop

            $Result | Should -Not -BeNullOrEmpty

            $Result.TechniqueID          | Should -BeExactly $ExpectedTechniqueID
            $Result.TestSuccess          | Should -BeTrue
            $Result.Method               | Should -BeExactly $Method
            $Result.SetKeyOnly           | Should -BeFalse
            $Result.KeyPath              | Should -BeExactly "HKEY_CURRENT_USER\$RegistryKeyPath"
            $Result.ValueName            | Should -BeExactly $ValueName
            $Result.ValueType            | Should -BeExactly 'Binary'
            $Result.ValueContent -is ([Byte[]]) | Should -BeTrue
            $Result.ValueContent.Count   | Should -Be 3
            $Result.ValueContent[0]      | Should -Be 1
            $Result.ValueContent[1]      | Should -Be 2
            $Result.ValueContent[2]      | Should -Be 3
            $Result.PreviousValueType    | Should -BeExactly 'String'
            $Result.PreviousValueContent | Should -BeExactly 'Hello'

            if ($Method -eq 'WMI') {
                $Result.ProcessId            | Should -BeNullOrEmpty
                $Result.ProcessPath          | Should -BeNullOrEmpty
                $Result.ProcessCommandLine   | Should -BeNullOrEmpty
            } else {
                $Result.ProcessId            | Should -Not -BeNullOrEmpty
                $Result.ProcessPath          | Should -Not -BeNullOrEmpty
                $Result.ProcessCommandLine   | Should -Not -BeNullOrEmpty
            }
            
            $Result.TestSampleContent    | Should -Not -BeNullOrEmpty
        } -TestCases @(
            @{ Method = 'PowerShell' },
            @{ Method = 'RegExeCommandLine' },
            @{ Method = 'WMI' }
        )

        It 'should set a DWord registry value for an existing registry value using the following method: <Method>' -Tag 'Technique', 'T1112' {
            # First, ensure that the key doesn't exist
            Remove-Item -Path "Registry::HKEY_CURRENT_USER\$RegistryKeyPath" -Force -ErrorAction Ignore

            # Ensure that the key and the value exist prior to the overwrite
            $null = New-Item -Path 'Registry::HKEY_CURRENT_USER\AtomicTestHarnesses' -Name 'T1112' -ErrorAction Stop
            Set-ItemProperty -Path 'Registry::HKEY_CURRENT_USER\AtomicTestHarnesses\T1112' -Name $ValueName -Type String -Value 'Hello' -ErrorAction Stop

            $Result = Set-ATHRegistry -Method $Method -Hive HKCU -KeyPath $RegistryKeyPath -ValueName $ValueName -ValueDword 4 -Force -ErrorAction Stop

            $Result | Should -Not -BeNullOrEmpty

            $Result.TechniqueID          | Should -BeExactly $ExpectedTechniqueID
            $Result.TestSuccess          | Should -BeTrue
            $Result.Method               | Should -BeExactly $Method
            $Result.SetKeyOnly           | Should -BeFalse
            $Result.KeyPath              | Should -BeExactly "HKEY_CURRENT_USER\$RegistryKeyPath"
            $Result.ValueName            | Should -BeExactly $ValueName
            $Result.ValueType            | Should -BeExactly 'DWord'
            $Result.ValueContent         | Should -Be 4
            $Result.PreviousValueType    | Should -BeExactly 'String'
            $Result.PreviousValueContent | Should -BeExactly 'Hello'

            if ($Method -eq 'WMI') {
                $Result.ProcessId            | Should -BeNullOrEmpty
                $Result.ProcessPath          | Should -BeNullOrEmpty
                $Result.ProcessCommandLine   | Should -BeNullOrEmpty
            } else {
                $Result.ProcessId            | Should -Not -BeNullOrEmpty
                $Result.ProcessPath          | Should -Not -BeNullOrEmpty
                $Result.ProcessCommandLine   | Should -Not -BeNullOrEmpty
            }
            
            $Result.TestSampleContent    | Should -Not -BeNullOrEmpty
        } -TestCases @(
            @{ Method = 'PowerShell' },
            @{ Method = 'RegExeCommandLine' },
            @{ Method = 'WMI' },
            @{ Method = 'VBScriptWscriptShellRegWrite' },
            @{ Method = 'JScriptWscriptShellRegWrite' }
        )

        It 'should set a QWord registry value for an existing registry value using the following method: <Method>' -Tag 'Technique', 'T1112' {
            # First, ensure that the key doesn't exist
            Remove-Item -Path "Registry::HKEY_CURRENT_USER\$RegistryKeyPath" -Force -ErrorAction Ignore

            # Ensure that the key and the value exist prior to the overwrite
            $null = New-Item -Path 'Registry::HKEY_CURRENT_USER\AtomicTestHarnesses' -Name 'T1112' -ErrorAction Stop
            Set-ItemProperty -Path 'Registry::HKEY_CURRENT_USER\AtomicTestHarnesses\T1112' -Name $ValueName -Type String -Value 'Hello' -ErrorAction Stop

            $Result = Set-ATHRegistry -Method $Method -Hive HKCU -KeyPath $RegistryKeyPath -ValueName $ValueName -ValueQword 4 -Force -ErrorAction Stop

            $Result | Should -Not -BeNullOrEmpty

            $Result.TechniqueID          | Should -BeExactly $ExpectedTechniqueID
            $Result.TestSuccess          | Should -BeTrue
            $Result.Method               | Should -BeExactly $Method
            $Result.SetKeyOnly           | Should -BeFalse
            $Result.KeyPath              | Should -BeExactly "HKEY_CURRENT_USER\$RegistryKeyPath"
            $Result.ValueName            | Should -BeExactly $ValueName
            $Result.ValueType            | Should -BeExactly 'QWord'
            $Result.ValueContent         | Should -Be 4
            $Result.PreviousValueType    | Should -BeExactly 'String'
            $Result.PreviousValueContent | Should -BeExactly 'Hello'

            if ($Method -eq 'WMI') {
                $Result.ProcessId            | Should -BeNullOrEmpty
                $Result.ProcessPath          | Should -BeNullOrEmpty
                $Result.ProcessCommandLine   | Should -BeNullOrEmpty
            } else {
                $Result.ProcessId            | Should -Not -BeNullOrEmpty
                $Result.ProcessPath          | Should -Not -BeNullOrEmpty
                $Result.ProcessCommandLine   | Should -Not -BeNullOrEmpty
            }
            
            $Result.TestSampleContent    | Should -Not -BeNullOrEmpty
        } -TestCases @(
            @{ Method = 'PowerShell' },
            @{ Method = 'RegExeCommandLine' },
            @{ Method = 'WMI' }
        )

        It 'should set String content for the "(Default)" registry value using the following method: <Method>' -Tag 'Technique', 'T1112' {
            # First, ensure that the key doesn't exist
            Remove-Item -Path "Registry::HKEY_CURRENT_USER\$RegistryKeyPath" -Force -ErrorAction Ignore

            $Result = Set-ATHRegistry -Method $Method -Hive HKCU -KeyPath $RegistryKeyPath -ValueName '(Default)' -ValueString 'Hello' -ErrorAction Stop

            $Result | Should -Not -BeNullOrEmpty

            $Result.TechniqueID          | Should -BeExactly $ExpectedTechniqueID
            $Result.TestSuccess          | Should -BeTrue
            $Result.Method               | Should -BeExactly $Method
            $Result.SetKeyOnly           | Should -BeFalse
            $Result.KeyPath              | Should -BeExactly "HKEY_CURRENT_USER\$RegistryKeyPath"
            $Result.ValueName            | Should -BeExactly '(Default)'
            $Result.ValueType            | Should -BeExactly 'String'
            $Result.ValueContent         | Should -Be 'Hello'
            $Result.PreviousValueType    | Should -BeNullOrEmpty
            $Result.PreviousValueContent | Should -BeNullOrEmpty

            if ($Method -eq 'WMI') {
                $Result.ProcessId            | Should -BeNullOrEmpty
                $Result.ProcessPath          | Should -BeNullOrEmpty
                $Result.ProcessCommandLine   | Should -BeNullOrEmpty
            } else {
                $Result.ProcessId            | Should -Not -BeNullOrEmpty
                $Result.ProcessPath          | Should -Not -BeNullOrEmpty
                $Result.ProcessCommandLine   | Should -Not -BeNullOrEmpty
            }
            
            $Result.TestSampleContent    | Should -Not -BeNullOrEmpty
        } -TestCases @(
            @{ Method = 'PowerShell' },
            @{ Method = 'RegExeCommandLine' },
            @{ Method = 'WMI' },
            @{ Method = 'VBScriptWscriptShellRegWrite' },
            @{ Method = 'JScriptWscriptShellRegWrite' }
        )
    }
}