Skip to content
This repository has been archived by the owner on Oct 4, 2024. It is now read-only.

Commit

Permalink
Merge pull request #180 from aaalzand/master
Browse files Browse the repository at this point in the history
New checks and minor enhancements
# Systems Manager/SSMAgent-Toolkit-Windows
  • Loading branch information
harniva14 authored Oct 6, 2021
2 parents f8aba4d + b701bf2 commit e001c86
Show file tree
Hide file tree
Showing 50 changed files with 1,340 additions and 889 deletions.
80 changes: 42 additions & 38 deletions Systems Manager/SSMAgent-Toolkit-Windows/README.md

Large diffs are not rendered by default.

Binary file modified Systems Manager/SSMAgent-Toolkit-Windows/SSMAgent-Toolkit.zip
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<#
.Synopsis
Get the application version number
.Description
This is a helper function to get the application version number.
.Example
Get-AppVersionNumber -Path 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall' -Value 'Environment'
.INPUTS
Path = The registry path
AppName = The name of the application under the DisplayName under the registry
.OUTPUTS
Return the version number under the registry
#>
function Get-AppVersionNumber {
[CmdletBinding()]
param (
[String]$RegHive = "LocalMachine",
[String]$Path = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", #Define the variable to hold the location of Currently Installed Programs
[parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]$AppName
)

if ((Get-WmiObject -Class Win32_ComputerSystem).SystemType -match 'x64') {
$RegView = [Microsoft.Win32.RegistryView]::Registry64
}
else {
$RegView = [Microsoft.Win32.RegistryView]::Registry32
}

#Create an instance of the Registry Object and open the HKLM base key
$reg = [microsoft.win32.registrykey]::OpenBaseKey([Microsoft.Win32.RegistryHive]::$RegHive, $RegView)

#Drill down into the Uninstall key using the OpenSubKey Method
$regkey = $reg.OpenSubKey($Path)

#Retrieve an array of string that contain all the subkey names
$subkeys = $regkey.GetSubKeyNames()

#Open each Subkey and use GetValue Method to check the match values for AppName
foreach ($key in $subkeys) {
$thisKey = $Path + "\\" + $key
$thisSubKey = $reg.OpenSubKey($thisKey)
if ($($thisSubKey.GetValue("DisplayName")) -eq $AppName) {
write-host $($thisSubKey.GetValue("DisplayVersion"))
return [System.Version]$($thisSubKey.GetValue("DisplayVersion"))
break
}
else {
continue
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,17 @@ function New-ProxyOutput {
)

If (-not (Test-RegistryValue -Path $Path -Value $Value)) {
$Message = "$Value = N/A."
$Note = "There is no $Value configured."
$Message = "$Value = N/A"
$Note = "There is no $Value configured"
Write-Log -Message "There is no http_proxy configured for $SettingName."
return $false, $Message, $note
}
else {
$Output = (Get-Item -Path $Path).GetValue($Value)
$Note = "$Value = $output."
$Note = "$Value = $output"
$Message = $note
Write-Log -Message "For $SettingName. $Value = $Output." -LogLevel "WARN"
return $true, $Message, $note
return $true, $Message, $Note
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,4 @@ function Test-RegistryValue {
Write-Log -Message $($PSitem) -LogLevel "ERROR"
return $false
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,21 @@
Get-AgentProxySettings -Message "Error message" -Key "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\AmazonSSMAgent"
.INPUTS
Key = The registry path.
Skip = Default is false. This script will be skipped if the agent is not installed.
Skip = Switch to skip this function if the agent is not installed.
.OUTPUTS
New-PSObjectResponse -Check "$check" -Status "$value" -Note "$note"
#>
Function Get-AgentProxySettings {
[CmdletBinding()]
param (
[String]$Key = "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\AmazonSSMAgent",
[String]$Skip = $false
[Switch]$Skip
)
$check = "SSM Agent Proxy Setting"
Write-Log -Message "New check....."
Write-Log -Message "$check"

if ($Skip -ne $true) {
if (-not ($Skip)) {
If (-not (Test-RegistryValue -Path $Key -Value 'Environment')) {
$value = "N/A"
$note = "There is no proxy setting for SSM Agent"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@
.Example
Get-IEProxySettings
.INPUTS
Skip = Default is false. This script will be skipped if the agent is not installed.
Key = The path for the Internet Explorer proxy in the registry. Default value: "Registry::HKEY_USERS\.DEFAULT\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings".
Skip = Switch to skip this function if the agent is not installed.
.OUTPUTS
New-PSObjectResponse -Check "$check" -Status "$value" -Note "$note"
#>
Function Get-IEProxySettings {
[CmdletBinding()]
param (
[String]$Key = "Registry::HKEY_USERS\.DEFAULT\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings",
[String]$Skip = $false
[Switch]$Skip
)

$check = "LocalSystem account user Internet Explorer proxy"
Expand All @@ -25,16 +26,16 @@ Function Get-IEProxySettings {
Write-Log -Message "For more information check - https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/security-identifiers-in-windows."
Write-Log -Message "IE proxy settings mainly used to enable PowerShell to have access to the internet (not Windows Update service)"

if ($Skip -ne $true) {
if (-not ($Skip)) {
If (((Get-Item -Path $Key).GetValue("ProxyEnable") -eq 0) -Or (-not (Test-RegistryValue -Path $Key -Value 'ProxyEnable'))) {
$value = "N/A"
$note = "There is no ProxyServer configured. Note: If the instance behind a proxy and PowerShell via run command has a command which needs access to the internet would fail if there are no Internet Explorer proxy settings."
$note = "There is no ProxyServer configured"
Write-Log -Message "There is noProxyServer configured for $check."
Write-Log -Message "Note: If the instance behind a proxy and PowerShell via run command has a command which needs access to the internet would fail if there are no Internet Explorer proxy settings"
}
else {
$value = "ProxyServer = " + (Get-Item -Path $Key).GetValue("ProxyServer") + ". ProxyOverride list = " + (Get-Item -Path $Key).GetValue("ProxyOverride")
$note = "Current IE proxy settings for LocalSystem account is " + (Get-Item -Path $Key).GetValue("ProxyServer") + " ProxyServer, and " + (Get-Item -Path $Key).GetValue("ProxyOverride") + " as ProxyOverride list. PowerShell would use these settings."
$note = "Current IE proxy settings for LocalSystem account is " + (Get-Item -Path $Key).GetValue("ProxyServer") + " ProxyServer, and " + (Get-Item -Path $Key).GetValue("ProxyOverride") + " as ProxyOverride list. PowerShell would use these settings"
Write-Log -Message $note -LogLevel "WARN"
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
.Example
Get-InstanceID -Token $token
.INPUTS
$Token = String.
$Token = String.
.OUTPUTS
Return the instance id.
#>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@
.Example
Get-LocalSystemAccountEnvironmentVariablesProxy
.INPUTS
Skip = Default is false. This script will be skipped if the agent is not installed.
Key = The path for the Local System Account Environment Variables proxy in the registry. Default value: "Registry::HKEY_USERS\.DEFAULT\Environment". Ref:https://docs.microsoft.com/en-us/windows/win32/procthread/environment-variables
Skip = Switch to skip this function if the agent is not installed.
.OUTPUTS
New-PSObjectResponse -Check "$check" -Status "$value" -Note "$note"
#>
Function Get-LocalSystemAccountEnvironmentVariablesProxy {
param (
[String]$Key = "Registry::HKEY_USERS\.DEFAULT\Environment", #https://docs.microsoft.com/en-us/windows/win32/procthread/environment-variables
[String]$Skip = $false
[Switch]$Skip
)

$check = "LocalSystem account user environment variable proxy"
Expand All @@ -24,18 +25,18 @@ Function Get-LocalSystemAccountEnvironmentVariablesProxy {
Write-Log -Message "For more information check - https://docs.microsoft.com/en-us/windows/win32/procthread/environment-variables."
Write-Log -Message "LocalSystem account user environment variable proxy mainly used by SSM Agent to connect to the endpoints"

if ($Skip -ne $true) {
if (-not ($Skip)) {
$http_proxy_check = New-ProxyOutput -Path $Key -Value 'http_proxy' -SettingName $check
$https_proxy_check = New-ProxyOutput -Path $Key -Value 'https_proxy' -SettingName $check
$no_proxy_check = New-ProxyOutput -Path $Key -Value 'no_proxy' -SettingName $check

If (($no_proxy_check[0] -eq $false) -and ($https_proxy_check[0] -eq $false) -and ($http_proxy_check[0] -eq $false)) {
$value = "N/A"
$note = "There is no http_proxy, https_proxy or no_proxy configured."
$note = "There is no http_proxy, https_proxy or no_proxy configured"
}
else {
$value = $http_proxy_check[1] + " " + $https_proxy_check[1] + " " + $no_proxy_check[1]
$note = $http_proxy_check[2] + " " + $https_proxy_check[2] + " " + $no_proxy_check[2]
$value = $http_proxy_check[1] + ". " + $https_proxy_check[1] + ". " + $no_proxy_check[1]
$note = $http_proxy_check[2] + ". " + $https_proxy_check[2] + ". " + $no_proxy_check[2]
}
}
else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,25 @@
This is a public function will create a schedule task under system account to make GetCallerIdentity api call - https://docs.aws.amazon.com/STS/latest/APIReference/API_GetCallerIdentity.html. This to returns the IAM user or role arn whose credentials are used to call the operation under LocalSystem account.
.Example
Get-LocalSystemAccountSTSCallerIdentity -ParentDirectoryLocation "C:\SSMAgent-Toolkit"
Get-LocalSystemAccountSTSCallerIdentity -ParentDirectoryLocation "C:\SSMAgent-Toolkit" -Skip $true
Get-LocalSystemAccountSTSCallerIdentity -ParentDirectoryLocation "C:\SSMAgent-Toolkit" -Skip
.INPUTS
$ParentDirectoryLocation - The location of the current module
$Skip - If this test would be skipped
$ParentDirectoryLocation = The location of the current module.
$Skip = Switch to skip this function if neither metadata or registration is accessible.
.OUTPUTS
New-PSObjectResponse -Check "$check" -Status "$value" -Note "$note"
#>
Function Get-LocalSystemAccountSTSCallerIdentity {
[CmdletBinding()]
param (
[String]$ParentDirectoryLocation,
[String]$Skip = $false
[Switch]$Skip
)

$check = "LocalSystem account user API assume role"
Write-Log -Message "New check....."
Write-Log -Message "$check"

if ($Skip -ne $true) {
if (-not ($Skip)) {
try {
$OutputPath = "$ParentDirectoryLocation\temp\STSCallerIdentity.xml"

Expand All @@ -45,14 +45,14 @@ Function Get-LocalSystemAccountSTSCallerIdentity {
$STSCallerIdentityARN = (Import-Clixml -Path $OutputPath).arn

$value = $STSCallerIdentityARN
$note = "The role and the instance in the ARN should match the role in the metadata and the current instanceID"
$note = "The role and the instance in the ARN should match the metadata\hybrid registration"
Write-Log -Message "The output of Get-STSCallerIdentity under the system account is $STSCallerIdentityARN."
}
catch {
Write-Log -Message "Failed..." -LogLevel "ERROR"
Write-Log -Message "$($_)" -LogLevel "ERROR"
$value = "Fail"
$note = "The process of creating and running the scheduled task failed. Please check the logs for more information."
$note = "The process of creating and running the scheduled task failed. Please check the logs for more information"
}
}
else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
StatusCode
Region
EC2InstanceID
ManagedInstance = Default is $false, if call the function with $true value will skip the check.
ManagedInstance = Switch to skip this function if the instance registered as hybrid instance.
.OUTPUTS
New-PSObjectResponse -Check "$check" -Status "$value" -Note "$note"
#>
Expand All @@ -20,13 +20,13 @@ Function Get-MetadataAccess {
[String]$StatusCode,
[String]$Region,
[String]$EC2InstanceID,
[String]$ManagedInstance = $false
[Switch]$ManagedInstance
)
$check = "EC2 instance metadata accessible"
Write-Log -Message "New check....."
Write-Log -Message "$check"

if ($ManagedInstance -ne $true) {
if (-not ($ManagedInstance)) {
#Check if there is access to the metadata
if ($StatusCode -eq 200) {
$value = "Pass"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
.Synopsis
Retrive the region from the metadata.
.Description
This is a public function used to retrive the region from the metadata using Invoke-CustomHTTPRequest function.
This is a public function used to retrieve the region from the metadata using Invoke-CustomHTTPRequest function.
.Example
Get-Region -Token $token
.INPUTS
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<#
.Synopsis
Check the installed and latest version of SSM Agent.
.Description
This is a public function used to check the SSM Agent version values for both installed and publicly available.
.Example
Get-SSMAgentVersion
.INPUTS
Region = The region to when SSM Agent register to.
RegistryHive = The registry hive where we look for installed applications. Default value: "LocalMachine".
RegistryPath = The path for the install applications in the registry. Default value: "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall".
Skip = Switch to skip this function if the service is not available.
.OUTPUTS
New-PSObjectResponse -Check "$check" -Status "$value" -Note "$note"
#>
Function Get-SSMAgentVersion {
[CmdletBinding()]
param (
[String]$Region,
[String]$RegistryHive = "LocalMachine",
[String]$RegistryPath = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", #Define the variable to hold the location of Currently Installed Programs,
[Switch]$Skip
)

$check = "SSMAgent version"
Write-Log -Message "New check....."
Write-Log -Message "$check"

if (-not ($Skip)) {
$LatestVersionUrl = "https://s3.$Region.amazonaws.com/amazon-ssm-$Region/latest/VERSION"
Write-Log -Message "Checking the latest SSM agent from $LatestVersionUrl."

try {
Write-Log -Message "Checking the install agent version from $RegistryHive`:\$RegistryPath"
$CurrentSSMAgentVersion = Get-AppVersionNumber -RegHive $RegistryHive -Path $RegistryPath -AppName "Amazon SSM Agent"
$CurrentSSMAgentVersion = [System.Version]$CurrentSSMAgentVersion
Write-Log -Message "The install SSM Agent version is $CurrentSSMAgentVersion"
}
catch {
Write-Log -Message ("Unable to retrieve the install SSM Agent version from $RegistryHive`:\$RegistryPath. " + $($PSitem.ToString())) -LogLevel "ERROR"
$CurrentSSMAgentVersion = [System.Version]"0.0.0.0"
}

try {
$LatestSSMAgentVersion = Invoke-RestMethod -Uri $LatestVersionUrl
Write-Log -Message "The latest agent version in $Region is $LatestSSMAgentVersion."
$value = "Pass"
if ([System.Version]$CurrentSSMAgentVersion -eq "0.0.0.0") {
$note = "The latest agent version in $Region is $LatestSSMAgentVersion"
}
elseif ([System.Version]$CurrentSSMAgentVersion -eq [System.Version]$LatestSSMAgentVersion) {
Write-Log -Message "The install and the latest agent version in $Region is $LatestSSMAgentVersion."
$note = "The install and the latest agent version in $Region is $LatestSSMAgentVersion"
}
elseif ([System.Version]$CurrentSSMAgentVersion -ne [System.Version]$LatestSSMAgentVersion) {
Write-Log -Message "The install SSM Agent version is $CurrentSSMAgentVersion, the latest in $Region is $LatestSSMAgentVersion."
$note = "The install SSM Agent version is $CurrentSSMAgentVersion, the latest in $Region is $LatestSSMAgentVersion"
}
}
catch {
if ([System.Version]$CurrentSSMAgentVersion -eq "0.0.0.0") {
$value = "N/A"
Write-Log -Message ("Unable to retrieve the install or latest SSM Agent version from $LatestVersionUrl. " + $($PSitem.ToString())) -LogLevel "ERROR"
$note = "Unable to retrieve the install or latest SSM Agent version"
}
else {
$value = "Pass"
Write-Log -Message ("Unable to retrieve the latest SSM Agent version from $LatestVersionUrl." + $($PSitem.ToString())) -LogLevel "ERROR"
$note = "The install SSM Agent version is $CurrentSSMAgentVersion"
}
}
}

else {
$value = "Skip"
$note = "This test skipped since the SSM Agent is not installed"
Write-Log -Message "The SSMAgent Version check skipped since the SSM Agent is not installed" -LogLevel "ERROR"
Write-Log -Message "Installing and configuring SSM Agent on EC2 instances for Windows Server - https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-install-ssm-win.html" -LogLevel "INFO"
}

return New-PSObjectResponse -Check "$check" -Status "$value" -Note "$note"
}
Loading

0 comments on commit e001c86

Please sign in to comment.