-
Notifications
You must be signed in to change notification settings - Fork 1
/
CreateAWSWindowsInstanceCP.ps1
137 lines (128 loc) · 6.19 KB
/
CreateAWSWindowsInstanceCP.ps1
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
##########################################################
# A function to create a random key name. Pass a number as the length
##########################################################
function GenerateKeyName ($length) {
return -join ((65..90) + (97..122) | Get-Random -Count $length | % {[char]$_})
}
##########################################################
# A function to check the instance status
##########################################################
function WaitForState ($instanceid, $desiredstate) {
while ($true) {
$a = Get-EC2Instance -Instance $instanceid
$state = $a.Instances[0].State.Name
if ($state -eq $desiredstate) {
break;
}
"$(Get-Date) Current State = $state, Waiting for Desired State=$desiredstate"
Sleep -Seconds 5
}
}
##########################################################
# Get AWS credentials from CyberArk Vault using CyberArk AIM
# Note: Any changes to the script done after the script has
# been signed to the Vault will cause this call to fail.
##########################################################
"$(Get-Date) Using AIM to retrieve AWS credentials from the Vault"
$CACLI = 'C:\Program Files (x86)\CyberArk\ApplicationPasswordSdk\CLIPasswordSDK.exe'
$appid = 'AWS_PowerShell'
$query = 'Safe=AWS;Folder=Root;Object=Cloud-Service-AWSAccounts-DemoAdminUser'
$output = 'PassProps.AWSAccessKeyID,Password'
$CAOutput = &$CACLI GetPassword /p AppDescs.AppId=$appid /p Query=$query /o $output
if ($CAOutput -eq $null) {
"$(Get-Date) Failed to get AWS Keys from CyberArk Vault"
}
else {
"$(Get-Date) Credentials retrieved, logging in to AWS"
# AWS authentication using access and secret key
$AWSAccessKey = $CAOutput.Split(",")[0]
$AWSSecretKey = $CAOutput.Split(",")[1]
Initialize-AWSDefaults -AccessKey $AWSAccessKey -SecretKey $AWSSecretKey -Region eu-west-2
# Create a Key Pair for the new instance and save a copy locally
$myKeyName = GenerateKeyName(10)
$myPSKeyPair = New-EC2KeyPair -KeyName $myKeyName
"$($myPSKeyPair.KeyMaterial)" | out-file -encoding ascii -filepath $env:temp\$myKeyName.pem
"KeyName: $($myPSKeyPair.KeyName)" | out-file -encoding ascii -filepath $env:temp\$myKeyName.pem -Append
"KeyFingerprint: $($myPSKeyPair.KeyFingerprint)" | out-file -encoding ascii -filepath $env:temp\$myKeyName.pem -Append
}
#Do we have the security group yet?
$sg = Get-EC2SecurityGroup | ? { $_.GroupName -eq "EC2RDPSecurityGroup"}
if ($sg -eq $null) {
#Create a Security Group
$sg = New-EC2SecurityGroup -GroupName EC2RDPSecurityGroup -GroupDescription "Security group for RDP only to EC2 instances"
Grant-EC2SecurityGroupIngress -GroupName EC2RDPSecurityGroup -IpPermissions @{IpProtocol = "tcp"; FromPort = 3389; ToPort = 3389; IpRanges = @("0.0.0.0/0")}
}
"$(Get-Date) Connected to AWS"
#Start creating new instance in AWS
$a = Get-EC2ImageByName -Name WINDOWS_2012R2_BASE
$imageid = $a.ImageId
$a = New-EC2Instance -ImageId $imageid -MinCount 1 -MaxCount 1 -InstanceType t2.micro -KeyName $myKeyName -SecurityGroups EC2RDPSecurityGroup
$instanceid = $a.Instances[0].InstanceId
"$(Get-Date) New Instance is being created: $instanceid"
WaitForState $instanceid "Running"
$a = Get-EC2Instance -Instance $instanceid
$publicIP = $a.Instances[0].PublicIpAddress
$publicDNS = $a.Instances[0].PublicDnsName
"$(Get-Date) Waiting for the new instance ($instanceid) password to become available"
$ec2_password = $null
# Wait until the password is available. According to AWS this could be up to 30 minutes.
$KeyFilePath = "$env:temp\$myKeyName.pem"
Sleep -Seconds 30
while ($ec2_password -eq $null) {
try {
$ec2_password = Get-EC2PasswordData -InstanceId $instanceid -PemFile $KeyFilePath -Decrypt
}
catch {
"$(Get-Date) Still waiting for password to be available..."
Sleep -Seconds 30
}
}
# This removes the only way to recover the password from AWS!
Remove-Item "$KeyFilePath"
"$(Get-Date) Got the new instance password! Lets create a new account in the Vault."
"$(Get-Date) Using AIM to retrieve a credentail with 'Add Account' rights"
$CACLI = 'C:\Program Files (x86)\CyberArk\ApplicationPasswordSdk\CLIPasswordSDK.exe'
$appid = 'AWS_PowerShell'
$query = 'Safe=AWS;Folder=Root;Object=Application-CyberArk-192.168.127.1-AWSAPIAdmin'
$output = 'PassProps.userName,Password'
$CAOutput = &$CACLI GetPassword /p AppDescs.AppId=$appid /p Query=$query /o $output
if ($CAOutput -eq $null) {
"$(Get-Date) Failed to get AWS Keys from CyberArk Vault"
}
else {
"$(Get-Date) Credentials retrieved, logging in to REST APIs"
$username = $CAOutput.Split(",")[0]
$password = $CAOutput.Split(",")[1]
$logonInfo = @{}
$logonInfo.username = $username
$logonInfo.password = $password
$FQDN = 'http://pvwa.cybergoose.demo'
$loginURI = $FQDN + '/PasswordVault/WebServices/auth/cyberark/CyberArkAuthenticationService.svc/logon'
#login to the Vault
$result = Invoke-RestMethod -Method Post -Uri $loginURI -ContentType "application/json" -Body (ConvertTo-Json($logonInfo))
"$(Get-Date) Vault login successful"
$logonToken = $result.CyberArkLogonResult
$createAccountURI = $FQDN + '/PasswordVault/WebServices/PIMServices.svc/Account'
#account parameters
$newAccounts = @{}
$newAccount = @{}
$newAccount.safe = "AWS"
$newAccount.platformID = "AWSWindowsServers"
$newAccount.address = $publicIP
#$newAccount.address = $publicDNS
$newAccount.username = "Administrator"
$newAccount.password = $ec2_password
$newAccount.accountName = $instanceid
$newAccounts.account = $newAccount
$headers = @{ "Authorization" = $logonToken }
#create the account in the Vault
$result = Invoke-RestMethod -Method Post -Uri $createAccountURI -headers $headers -ContentType "application/json" -Body (ConvertTo-Json($newAccounts))
"$(Get-Date) Account created successfully"
$logoffURI = $FQDN + '/PasswordVault/WebServices/auth/cyberark/CyberArkAuthenticationService.svc/logoff'
#logoff from the Vault
$result = Invoke-RestMethod -Method Post -Uri $logoffURI -headers $headers -ContentType "application/json" -Body (ConvertTo-Json($logonInfo))
"$(Get-Date) Vault logoff successful"
"$(Get-Date) Finished provisioning instance in AWS and the privileged account of instance $instanceid, with IP address $publicIP in the CyberArk Vault"
# Clear AWS credentials
Clear-AWSDefaults
}