I'm trying to get the volume id of an EC2 instance based on a tag letter, which I can do fine, but I then want to get the tag called name which is the description of the EC2 instance so i can then create a snapshot based on volume id and assign the EC2 instance description to it
#gets current date
$backupDate = Get-Date -f 'yyyy-MM-dd'
#Retrieve all volumes that should be backed up based on the Key called Backup with the Value of D
$backupVolumes = Get-Ec2Volume -ProfileName qa | ? { $.Tags.Key -eq "Backup" -and $.Tags.Value -eq "D" } | select -expand VolumeId
#This gets all instances running and lists them
$instanceName = Get-EC2Tag -ProfileName qa | ? { $.ResourceType -eq 'instance' -and $.Key -eq 'Name'}
#Backup each volume and apply tag information to the volume and snapshot
Foreach ($backupVolume in $backupVolumes)
{
$snapshot = New-Ec2snapshot -ProfileName qa -VolumeId $backupvolume -Description "Backup for $instanceName - $backupDate"
}
Above is what i'm trying to run, so the first line grabs the volumeid based on the tag value of D then the second line grabs the instance name, But I want it to only get the instance name based on the volume id listed, so I can pass this onto the Foreach loop and set the -Description
The code for getting the Name tag from the instance needs to be within the loop, then it gets the Tag that is associated with each Volume:
I've also changed the way you are filtering, using -Filter rather than where is more efficient as it returns the filtered data directly.
$backupDate = Get-Date -f 'yyyy-MM-dd'
$backupVolumes = Get-Ec2Volume -Filter #{ Name='tag:Backup';Value='D'}
foreach ($backupVolume in $backupVolumes) {
$instanceId = $backupVolume.Attachment.instanceid
$volumeId = $backupvolume.VolumeId
$instanceName = Get-EC2Tag -Filter #{ Name='resource-id';Value=$instanceid} | Where-Object Key -EQ Name | Select-Object -ExpandProperty Value
New-EC2Snapshot -VolumeId $volumeId -Description "Backup for $instanceName - $backupDate" -WhatIf
}
Note: You'll need to add ProfileName back in where appropriate, and remove WhatIf as this is only needed to test the code.
Related
Long time lurker, first time poster. I've come across a bit of a problem so I figured I'd ask for help.
I'm following these instructions in order to get a popup message to appear once a user logs into an AWS workspace.
The script fully works, but the issue is that the window is able to be moved/resized and the user can still use the computer while the window is up.
I want to modify the script so that the popup window is FORCED to be interacted with (I.E. Click "OK" or "Logoff") before the user can click anything else on the computer.
How can this be done?
NOTE: I CAN NOT use the Interactive Login: Logon Text/Title GPO settings as it won't work in AWS workspaces.
Below is the code provided by AWS:
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing");
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms");
$objForm = New-Object System.Windows.Forms.Form;
# Removes the minimize, maximize and exit boxes from the top of the form.
$objForm.ControlBox = $False
$objForm.Text = "Security and Legal Notice";
$objForm.Size = New-Object System.Drawing.Size(640,480);
$objForm.StartPosition = "CenterScreen";
$objForm.KeyPreview = $True;
$objForm.Add_KeyDown({if ($_.KeyCode -eq "Enter")
{$objForm.Close()}})
$objForm.Add_KeyDown({if ($_.KeyCode -eq "Escape")
{$objForm.Close();logoff}})
$OKButton = New-Object System.Windows.Forms.Button;
$OKButton.Location = New-Object System.Drawing.Size(250,400);
$OKButton.Size = New-Object System.Drawing.Size(75,23);
$OKButton.Text = "OK";
$OKButton.Add_Click({$objForm.Close()});
$objForm.Controls.Add($OKButton);
$CancelButton = New-Object System.Windows.Forms.Button;
$CancelButton.Location = New-Object System.Drawing.Size(325,400);
$CancelButton.Size = New-Object System.Drawing.Size(75,23);
$CancelButton.Text = "Logoff";
$CancelButton.Add_Click({$objForm.Close();logoff});
$objForm.Controls.Add($CancelButton);
$objLabel = New-Object System.Windows.Forms.Label;
$objLabel.Location = New-Object System.Drawing.Size(10,20);
$objLabel.Size = New-Object System.Drawing.Size(600,400);
$objLabel.Text = "You are accessing a restricted system for official use only.
By selecting OK you agree to abide by all organizational security policies.
Do not allow unauthorized personnel to access this system."
$objForm.Controls.Add($objLabel);
$objForm.Topmost = $True;
$objForm.Add_Shown({$objForm.Activate()});
[void] $objForm.ShowDialog();
I am trying to run below command on AWS SSM:
Parameters = #{
commands = #(
"Write-Host userid is $userID password $($password)"
'$userID2 = $userID'
'$password2 = $password'
"Write-Host userid is $userID2 password $($password2)"
)
}
First Write-Host statement prints the correct values of $userID and $password but after the assignment of the new variable, second Write-Host variable prints empty for both variables. Am I doing something wrong? I tried fetching the values of $userID and $password with double quotes as well but no luck.
For anyone facing the same issue. Problem is that before sending the commands to EC2, AWS will replace the commands with all variable values and hence, we cannot reuse the variables inside the commands directly. This is the workaround I had to come up with:
$userID = 'testuser1'
$password = 'testpassword'
$userIdString = "`$userID2 = '$userID'"
$passwordString = "`$password2 = '$password'"
Parameters = #{
commands = #(
"Write-Host userid is $userID password $($password)"
"$userIdString"
"$passwordString"
"Write-Host userid is $userID2 password $($password2)"
)
}
Now it prints the $userID2 and $password2 fine.
I am new to powershell and wants to know if there is way to tag Dynamo DB table (name: Testname) from powershell.
I did try these commands: Add-DDBResourceTag -ResourceArn $dbarn -Tag #{Key="Department";Value="Stage"}
where $dbarn is arn of DBtable 'Testname'.
Tag should be created as an object in powershell of type Amazon.Dynamodbv2.Model.Tag
Something like this
$Tagobject = New-Object Amazon.Dynamodbv2.Model.Tag
$Tagobject.Key = "Environment"
$Tagobject.Value = "Prod"
You can then use your command
Add-DDBResourceTag -ResourceArn $dbarn -Tag $Tagobject
Ok here it is, sweet and simple. I need to verify that a list of groups were added to the local admin group in a new build (among other things) so I can promote the servers to prod...
So far, I can get the groups, and output the Boolean to a file on the remote server, get that content ( I am thinking I should be piping it but don't know how). What I would like to do, is return a set of variables with the group name and whether or not it exists in the local admin group. But ... that is not what happens...
Sorry for the rudimentary ifElse clauses, my humble skills are not the slickest... Here is the code I have been working with -Thanks in advance!:
$MemberNames = #()
$Servers = $HostName
foreach ( $Server in $Servers ) {
$Group= [ADSI]"WinNT://$Server/$LocalGroup,group"
$Members = #($Group.psbase.Invoke("Members"))
$Members | ForEach-Object {
$MemberNames += $_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)
}
$ChildGroups | ForEach-Object {
$output = "" | Select-Object Group, InLocalAdmin
$output.Group = $_
$output.InLocalAdmin = $MemberNames -contains $_
Write-Output $output | Export-Csv -Path "c:\VerifyGroups.csv" -Append
#$output.Group "is in the Local Admin Group" $output.InLocalAdmin #| Export-Csv -Path "c:\VerifyGroups.csv" -Append
# }
}
#Validate local admin group membership
Get-Content -Path "c:\VerifyGroups.csv"
ForEach ($_){
if ($string -match "Domain Admins" -and "True") {$ResDomainAdminGrp = "Validation Passed: Domain Admin Group is a member of the Local Admin Group" }
elseif ($string -match "Domain Admins" -and "False") {$ResDomainAdminGrp = "Validation Failed: Domain Admin Group is not a member of the Local Admin Group" }
elseif ($string -match "Enterprise Backup Admins" -and "True") {$ResEntBaKAdmGrp = "Validation Passed: Enterprise Backup Admins is a member of the Local Admin Group" }
elseif ($string -match "Enterprise Backup Admins" -and "False") {$ResEntBaKAdmGrp = "Validation Failed: Enterprise Backup Admins is not a member of the Local Admin Group" }
elseif ($string -match "Enterprise Server Admins" -and "True") {$ResEntSvrAdmGrp = "Validation Passed: Enterprise Server Admins is a member of the Local Admin Group" }
elseif ($string -match "Enterprise Server Admins" -and "False") {$ResEntSvrAdmGrp = "Validation Failed: Enterprise Server Admins is not a member of the Local Admin Group" }
elseif ($string -match "Enterprise SQLDB Admins" -and "True") {$ResEntSQLAdmGrp = "Validation Passed: Enterprise SQLDB Admins is a member of the Local Admin Group" }
elseif ($string -match "Enterprise SQLDB Admins" -and "False") {$ResEntSQLAdmGrp = "Validation Failed: Enterprise SQLDB Admins is not a member of the Local Admin Group" }
elseif ($string -match "Enterprise SVC Admins" -and "True") {$ResEntSVCAdmGrp = "Validation Passed: Enterprise SVC Admins is a member of the Local Admin Group" }
elseif ($string -match "Enterprise SVC Admins" -and "False") {$ResEntSVCAdmGrp = "Validation Failed: Enterprise SVC Admins is not a member of the Local Admin Group" }
else {}
}
You could clean up a little bit, by making an array of the items you want to check and loop over that array.
$group =[ADSI]"WinNT://./Administrators,group"
$members = #($group.psbase.Invoke("Members")) | foreach {$_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)}
$List = "Domain Admins","Enterprise Backup Admins"
foreach ($item in $list) {
if ($members -contains $item) {
"Validation Passed: $item is a member of the local admin group."
} else {
"VALIDATION FAILED: $item is not a member of the local admin group."
}
}
Ok, after much ado, I abandoned the above code, in favor of this easier approach. A bit less robust, but simple and gets the job done... Naturally, if you have more groups to verify, then just add more if statements with corresponding variables.
Enjoy:
$group =[ADSI]"WinNT://./Administrators,group"
$members = #($group.psbase.Invoke("Members"))
$VerAdminGrp01 = ($members | foreach {$_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)}) -contains "Domain Admins"
if($VerAdminGrp01){$ResDomAdmin = "Validation Passed: Domain Admins is a member of the local admin group."}
Else {$ResDomAdmin = "VALIDATION FAILED: Domain Admins is not a member of the local admin group."}
$VerAdminGrp02 = ($members | foreach {$_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)}) -contains "Enterprise Backup Admins"
if($VerAdminGrp02){$ResEntBakAdmin = "Validation Passed: Enterprise Backup Admins is a member of the local admin group."}
Else {$ResEntBakAdmin = "VALIDATION FAILED: Enterprise Backup Admins is not a member of the local admin group."}
I need to check a list (.txt) of IP's (or hostnames) to find if they are domain connected or not and perform a task accordingly. I found this post here (How to find if the local computer is in a domain?) which is almost exactly what I'm after except it does it for the local machine. I tried to modify the script to suit but I don't have much experience with PowerShell.
If anyone is able to help it would be much appreciated.
Cheers
David
You can use the code with -Computername parameter and provide explicit credentials in case the remote computer administrator credentials are different from what you are using.
$cred = Get-Credential
$servers = Get-Content C:\scripts\Servers.txt
Foreach ($server in $servers) {
if ((gwmi win32_computersystem -computername $server -Credential $cred).partofdomain -eq $true) {
#Do something Here
} else {
#Do something Here
}
If you have a list of valis server names, you could check if they have a corresponding computer account in AD:
Get-Content .\Servers.txt | Foreah-Object {
if(Get-ADComputer -Filter {Name -eq $_})
{
"machine $_ is a part of default domain"
}
else
{
"machine $_ IS NOT a part of default domain"
}
}