Unable to reboot instance from aws ssm association - windows

So I have an SSM association that would run a AWS-RunRemoteScript document to call a Powershell script that would run commands for domain join.
Its successfully doing the domain join but after I try to do a exit 3010, which return a 255 exit status and my script fails.
My AWS-RunRemoteScript document accepts some params. Below is the snippet in my powershell script.
try {
$ansible_token = (Get-SECSecretValue -SecretId $ansibletoken_secretname -Select SecretString | ConvertFrom-Json | Select -ExpandProperty token)
$instanceid = Invoke-RestMethod -Uri "http://169.254.169.254/latest/meta-data/instance-id"
$limit = $instanceid + ",127.0.0.1"
If((gwmi win32_computersystem).partofdomain -ne $True) {
Write-Host "Instance not joined to domain. Running domain join ansible template.."
$domain_join_success = Run-AnsibleJob $domain_join_template $extra_vars_param_domain_join $limit $ansible_token $tower_url
if ($domain_join_success -eq $True)
{
Write-Host "Shutting Down Instance $($instanceid).." --> This is printed and then I get a 255.
exit 3010
}
}
If((gwmi win32_computersystem).partofdomain -eq $True)
{
Write-Output "The instance is domain joined, running node setup ansible template.."
$node_initialize_success = Run-AnsibleJob $initialize_node_template $extra_vars_param_initialize_node $limit $ansible_token $tower_url
If($node_initialize_success -eq $True)
{
exit 0
}
}
}
catch {
Write-Host "--------------Error Occured----------------"
Write-Host $_
}
exit 1
Run-AnsibleJob is a function which calls an ansible job and returns tru if it is successful, and false if it fails.
What am doing wrong?

Related

How to test a boolean in powershell?

I have a powershell script which looks to make sure someone is running the script as an admin.
The variable $currentPrincipal returns true or false.
Here is the code:
$currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
$currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
If ($currentPrincipal -eq $true) {
Write-host "yay"
}
Else {
Write-Host "boo"
}
But when running as an admin AND currentPrincipal is true, it still falls through to the else... here is the CLI which shows that:
PS C:\WINDOWS\system32> C:\Users\dogzilla\Desktop\SetSQLServerToManual.ps1
True
boo
My question is, what is the proper way to evaluate a boolean in powershell?
Your currently just calling WindowsPrincipal.IsInRole, which will output the Boolean result. Additionally, $currentPrincipal is of type System.Security.Principal.WindowsPrincipal, which is not a Boolean. I would ammend your code to store the result of IsInRole() as a variable and checking that instead.
$currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
$checkRole = $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
If ($checkRole -eq $true) {
Write-host "yay"
}
Else {
Write-Host "boo"
}
This is the way to test it:
if ( ($currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) -eq $true )

How to correctly compose Invoke-Expression command to build variable value based on config file values

Please see latest code that is now working, there is no longer any need for any Invoke cmdlet:
$ClassificationList = $null
$classifications = $null
$ClassificationList = $ConfigFile.Settings.Project.Classifications
If ( $ClassificationList )
{
$ClassificationList = $ClassificationList -replace ',','|'
$classifications = $wsus.GetUpdateClassifications() |
where title -match $ClassificationList
$updatescope.Classifications.Clear()
$updatescope.Classifications.AddRange($classifications)
}
Original Question:
This question has been condensed to avoid confusion.
When executing the below code:
$ScriptText =
#"
`$classifications = `$wsus.GetUpdateClassifications() |
? {
$_.Title -eq 'Critical Updates' `
-OR `
$_.Title -eq 'Security Updates' `
-OR `
$_.Title -eq 'Definition Updates'
}
"#
$scriptBlock = [Scriptblock]::Create($ScriptText)
Invoke-Command -ScriptBlock {$scriptBlock}
Write-Host $classifications
The variable $classifications does not get populated, but executing the code without wrapping it into a script block works fine. I am trying to read from a config file all classifications I want to search WSUS for and dynamically add them to the above script, but executing that script when it is built does not appear to work, though no errors are thrown.
I would do it this way.
$wsus.GetUpdateClassifications() |
where title -match 'critical updates|security updates|definition updates'
Don't define your code as a string and then put that string in a scriptblock.
Invoke-Command -Scriptblock {$ScriptText}
If you must create a scriptblock from a string you'd do it like this:
$ScriptText = "if ( 1 -ne 2 ) {
Write-Host 'Hello'
} else {
Write-Host 'GoodBye'
}"
Invoke-Command -ScriptBlock ([Scriptblock]::Create($ScriptText))
However, normally you'd create the scriptblock as a literal, either as a variable
$scriptblock = {
if ( 1 -ne 2 ) {
Write-Host 'Hello'
} else {
Write-Host 'GoodBye'
}
}
Invoke-Command -ScriptBlock $scriptblock
or inline
Invoke-Command -ScriptBlock {
if ( 1 -ne 2 ) {
Write-Host 'Hello'
} else {
Write-Host 'GoodBye'
}
}

Powershell $? in do until loop

I'm trying to make a loop for joining a Windows domain in PowerShell with usage of $?, which should return false/true if last command returned error or not.
This is what I got:
Add-Computer -DomainName "domainname.local" -Credential "admin"
$MaxAttempts = 0
do {
if ($? -like "false" -and $MaxAttempts -lt 5) {
$MaxAttempts += 1
Write-Host "Attempt" $MaxAttempts "out of 5"
Add-Computer -DomainName "domainname.local" -Credential "admin"
} else {
Write-Host "test"
}
Problem is when I have first command outside of that do/until loop it's returning true even when I get an error.
But when I add this command to do/until loop it returns false as expected but that way im running that command twice and that's not I want.
Can someone explain me this sorcery?
The automatic variable $? contains true or false depending on whether or not the previous PowerShell statement completed successfully. The last PowerShell statement before you check the value of $? inside the loop is $MaxAttempts = 0, which changes the value of $? to true (because the assignment operation succeeded), even if the Add-Computer statement before that failed.
I'd recommend adjusting your loop to something like this:
$MaxAttempts = 0
do {
Add-Computer -DomainName "domainname.local" -Credential "admin"
$success = $?
if (-not $success) {
$MaxAttempts++
}
} until ($success -or $MaxAttempts -ge 5) {

Check server before starting service

I need to edit a script. There is a service that is on two Windows Server 2008 R2. They are load balanced. I need it so when I run the script that starts the service on the primary server and the secondary, so before it even start the service on both servers, the goes out and checks to ensure the primary server is up and running, then continues on as normal to start the services on both servers.
# Start Appian
function StartAppian {
$APNSVC = Get-Service -Name $AppianService
if (!$APNSVC) {
Write-Host "Appian Service does not exist"
return
}
# Check to see if Appian's service is already started
if ($APNSVC.Status -eq "Running") {
if ($LB) {
if ($MULEAPNSVC.Status -eq "Running") {
Write-Host "Appian Service on the Load Balanced Server already is started!" -ForegroundColor Yellow
return
}
}
Write-Host "Appian Service already is started!" -ForegroundColor Yellow
Read-Host "Press any key to return"
return
}
# Check if DEV's Process Design has a writing_*.kdb file and delete it
if ($Server -eq "DEV") {
#gw1
if (Test-Path $APPIAN_HOME\server\process\design\gw1\writing_*.kdb) {
Write-Host "Removing writing_*.kdb from GW1" -ForegroundColor Yellow
Remove-Item $APPIAN_HOME\server\process\design\gw1\writing_*.kdb
}
#gw2
if (Test-Path $APPIAN_HOME\server\process\design\gw2\writing_*.kdb) {
Write-Host "Removing writing_*.kdb from GW2" -ForegroundColor Yellow
Remove-Item $APPIAN_HOME\server\process\design\gw2\writing_*.kdb
}
}
Write-Host "Starting Appian"
# Place the name of the service here to start for Appian
Start-Service $AppianService
Notify("StartAppian")
if ($LB) {
(Get-Service $MULEAPNSVC.Name -ComputerName $MULE).Start()
Write-Host "Starting Mule's Appian" -ForegroundColor Magenta
}
cmd.exe "/C $APPIAN_HOME\server\_scripts\diagnostic\checkengine.bat -s > $logdir\Startup.log"
# These lines check the Startup log for fatals and errors at the beginning
$fatals = Select-String FATAL $logdir\Startup.log
$errs = Select-String ERROR $logdir\Startup.log
# Check for errors and fatals again
$fatals = Select-String FATAL $logdir\Startup.log
$errs = Select-String ERROR $logdir\Startup.log
Write-Host "Still warnings or Errors in CE" -ForegroundColor Yellow
# Increment times
$times = $times + 1
# If times > threshold, email out error message
if ($times -gt $threshold) {
SendAlert("There is a problem with Appian - It won't start")
Write-Host "There was a problem with Appian..it took too long to start - emailing alert" -ForegroundColor Red
Read-Host "Press any key to exit"
}
}
Write-Host "Appian Started" -ForegroundColor Green
Read-Host "Press any key to return"
}
You can do that with a simple Test-Connection at the start of the script.
if ($ping = Test-Connection -ComputerName PrimaryServerName -Quiet) {
Write-Host "Host avalible"
}
else {
Write-Host "Host unavalible"
Exit
}
any other suggestions?
if (Test-Connection ServerName -Count 1 -Quiet) {
Write-Host "Host avalible"
}
else {
Write-Host "Host unavalible"
Exit
}
this doesnt work. I want it to test the if the server is up or not, if its not, exit the script, if it is, continue on with the script. When testing this on ISE it work, but when i launch the script it doesn't

Powershell Retrieve-Job gives "cannot index into null array error"

I am trying to test if two PC's are connected by using the following script
$array ='PC1','PC2'
for ($i=0; $i -lt $array.length; $i++) {
Start-Job –Name TestConnection$i –Scriptblock {
if(test-connection $array[$i] -count 1 -quiet){
write-host Success
}
else { write-host No connection
}
}
}
When I try to do Receive-Job for either one I get "Cannot index into a null array".
What am I doing wrong?
You need to pass in the PC name as an argument, as the array does not exist in the context of the script block, like this:
$array ='PC1','PC2'
for ($i=0; $i -lt $array.Length; $i++) {
Start-Job –Name TestConnection –Scriptblock {
param($pcName)
if(Test-Connection $pcName -Count 1 -Quiet) {
Write-Host Success
} else {
Write-Host No connection
}
} -ArgumentList $array[$i]
}
You have to pass $i (and any other variables) via -ArgumentList through the Start-Job Cmdlet since your script block is running in an entirely different powershell host and doesn't have access to anything inside the shell that started the job.
Even though your script block exists inside the original code, Powershell does not expand any variables in it until it's executing the code in the other host. You can define param() at the beginning of your script block to use the variable you pass via -ArgumentList

Resources