PowerShell Datatype Declaration

PowerShell is a scripting and not a programming language, that much I know. Sometimes I am still missing a strict(er) datatype declaration to prevent a lot of mistakes caused by none or (automatically) false declared variables.

Have a look at the examples below and let me know what you think of it 🙂

1
2
3
4
2+"5" # => 7 
"2"+5 # => 25
[int]"2"+5 # => 7
[string]2+"5" # => 25

In my opinion all of the above examples should throw an error while the following ones should not:

1
2
3
4
2+5 # => 7
"2"+"5" # => 25
[int]2+5 # => 7
[string]"2"+"5" # => 25

Meltdown and Spectre Remote Vulnerability Check on Windows Systems

Given PowerShell remoting is activited on the Windows Computers in your environemnt, there is an easy solution to check if those systems are vulnerable or not (any more).
The script as follwos retrieves all computer objects from Active Directory

Make sure the computer on which you run this script has the Active Directory PowerShell module as well as the SpeculationControl PowerShell module installed and your currently logged in user has the appropriate permissions granted.

1
2
3
4
Import-Module -Name SpeculationControl
Get-ADComputer -Filter * | foreach {
    Invoke-Command -ComputerName $_.DNSHostName ${function:Get-SpeculationControlSettings}
}

How to use certutil output as Objects within PowerShell

Working with Certification Authorities (CA), native PowerShell commands are not too well established yet to fit all my needs, so I had to think about a solution how I could use the well-known certutil tool and use its output within PowerShell.

That is what I came up with (thanks to Shane’s blogpost):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
function certutilToObjectList($certutilOutput){
 
    $certutilObjectList = @()
    $currentKey = $null
    $currentValue = $null
    $certutilOutput -split [environment]::NewLine | foreach {
 
        switch -regex ($_){
 
            '[Entry|Row] \d+:(.*)' {
                # New Object found
                $currentObject = New-Object psobject
                $currentValue = $null
                continue
            }
 
            '(\s{2})(?[\w\s]+):\s*(?.*)' {
                # Add key / value pair to Object
                if($currentObject){ 
                    if( -not $matches.value){
                        $currentKey = $matches.key.Trim()
                        $currentValue = $null
                    }
                    else {
                        $currentObject | Add-Member -MemberType NoteProperty -Name $($matches.key.Trim()) -Value $($matches.value.trim(@("'",'"','`'))) -Force 
                    }
                }
            }
 
            '^$' {
                # Add Object to ObjectList if Object exists
                if($currentObject){ 
                    if($currentKey -and $currentValue){
                        $currentObject | Add-Member -MemberType NoteProperty -Name $($currentKey) -Value $($currentValue) -Force 
                    }
                    $certutilObjectList += $currentObject 
                    $currentObject = $null
                    $currentKey = $null
                    $currentValue = $null
                }
            }
 
            default {
                # Save Values of Multiline Parameters if a current Key exists
                if($currentObject -and $currentKey){ 
                    $currentValue += $_+"`n"
                }
            }
        }
    }
 
    # Add last Object to ObjectList if necessary
    if($currentKey -and $currentValue){
        $currentObject | Add-Member -MemberType NoteProperty -Name $($currentKey) -Value $($currentValue) -Force 
    }
    $certutilObjectList += $currentObject
 
    return $certutilObjectList
}
 
 
$certutil = "$($env:SystemRoot)\system32\certutil.exe"
$certutilOutput = Invoke-Expression "$certutil -view -restrict disposition==20 -out 'serialnumber,requestid,Issued Common Name,Certificate Expiration Date'"
$certutilObjectList = certutilToObjectList $certutilOutput

This function splits the certutil output into single rows and processes them one by one using regular expressions to figure out what to do with each row. It further creates a list (array) of PowerShell objects to make the output easily usable with PowerShell.

Read More

How to change your Password in a Remote Session (Windows Security)

Using a jump server to connect from your computer to different servers in your network makes it quite uncomfortable to change your password in a Windows Server 2012 environment.

Pressing Ctrl + Alt + End (instead of Delete) opens Windows Security on the jump server and not on the server you are remoting on using the jump server.

There is an easy solution, though: create a new .vbs file on the remote computer i.e. “WindowsSecurity.vbs” and add the following code:

1
2
Set objShell = CreateObject("Shell.Application")
objShell.WindowsSecurity

Now all you have to do is just double click the file and Windows Security pops up which allows you to change your password.

Creating a ZIP Archive with PowerShell Version <5.0

The PowerShell command “Compress-Archive” comes pretty handy when it comes to creating a .zip file/archive. Sadly it only available since PowerShell version 5.0. which comes with Windows 10 (can be installed on Windows 8.1 and Windows Server 2012 R2 as well, though).
No worries, there is a solution as well which works with Powershell <5.0. The following function requires the output filename e.g. "C:\temp\MyOutputArchive.zip" and the full path of the directory to be archived eg. "C:\temp\ToBeArchived\".

1
2
3
4
5
function createZipFile($outputFileName, $sourceDirectory){
    Add-Type -AssemblyName System.IO.Compression.FileSystem
    $compressionLevel = [System.IO.Compression.CompressionLevel]::Optimal
    [System.IO.Compression.ZipFile]::CreateFromDirectory($sourceDirectory, $outputFileName, $compressionLevel, $false)
}