$SW_Server = "" $SQL_Server = "" $AWS_GroupName = 'Amazon AWS' #FUNCTIONS #IPAM Update Functions #insert/update IPAM VPC folder based on existance within Solarwinds Function Upsert-AWS-VPC{ Param ( [array]$vpcs, [SolarWinds.InformationService.Contract2.InfoServiceProxy]$swis, [string]$AWS_RootID ) Process{ foreach ($vpc in $vpcs) { $name = $vpc.Name $ip = $vpc.CidrBlock.Split('/')[0] $cidr = $vpc.CidrBlock.Split('/')[1] $AWS_GroupID = Get-SwisData -SwisConnection $swis ` -Query "SELECT TOP 1 GroupId FROM IPAM.GroupNode where address = '$ip' and cidr = '$cidr' " if ($AWS_GroupID -eq $null) { "create $ip - $cdr " Invoke-SwisVerb $swis IPAM.SubnetManagement CreateSubnet @($ip, $cidr ) } #update properties # subnetID and URI are both IDs that refer to the same object $URI = Get-SwisData -SwisConnection $swis ` -Query "SELECT TOP 1 URI FROM IPAM.GroupNode where address = '$ip' and cidr = '$cidr' " $SubnetID = Get-SwisData -SwisConnection $swis ` -Query "SELECT TOP 1 GroupID FROM IPAM.GroupNode where address = '$ip' and cidr = '$cidr' " #disable auto scan # We do NOT want solarwinds ICMP scanning and changing the staus of things. Also means we # need to manage everything including (I think?) DNS and host data. Invoke-SwisVerb $swis IPAM.SubnetManagement ChangeDisableAutoScanning @( $SubnetID, "false") #set custom properties #not supported yet by API #Set-SwisObject $swis -Uri $URI -Properties @{Object_ID=$ff} #Set-SwisObject $swis -Uri $URI -Properties @{aws_cloudformation_logical_id=$ff} #Set-SwisObject $swis -Uri $URI -Properties @{aws_cloudformation_stack_id=$ff} #Set-SwisObject $swis -Uri $URI -Properties @{aws_cloudformation_stack_name=$ff} #Set-SwisObject $swis -Uri $URI -Properties @{OwnerId=$ff} $sql = " update [SolarWindsOrion].[dbo].[IPAM_GroupAttrData] SET [Object_ID] = '" + $vpc.vpcid + "' ,[aws_cloudformation_logical_id] = '"+ $vpc.'aws:cloudformation:logical-id' +"' ,[aws_cloudformation_stack_id] = '"+ $vpc.'aws:cloudformation:stack-id' +"' ,[aws_cloudformation_stack_name] = '"+ $vpc.'aws:cloudformation:stack-name' +"' ,[OwnerId] = '"+ $vpc.OwnerId +"' where groupid = $SubnetID" $rs = Invoke-Sqlcmd -ServerInstance $SQL_Server -Database SolarwindsOrion -Query $sql #set basic properties #note groupType=4 means supernet $sql = " update dbo.ipam_group SET parentid = $AWS_RootID ,FriendlyName = '" + $vpc.Name + "' + Address + ' /' + cast(CIDR as varchar(10)) ,GroupType = 4 where groupid = $SubnetID" $rs = Invoke-Sqlcmd -ServerInstance $SQL_Server -Database SolarwindsOrion -Query $sql } } } #insert/update IPAM folder based #this still needs writing. Currently just a copy of the code for the above function as it will be similar. #we do not need to change our subnet to a supernet. Function Upsert-AWS-Subnet{ Param ( [array]$vpcs, [SolarWinds.InformationService.Contract2.InfoServiceProxy]$swis, [string]$VPC_ID ) Process{ foreach ($vpc in $vpcs) { $name = $vpc.Name $ip = $vpc.CidrBlock.Split('/')[0] $cidr = $vpc.CidrBlock.Split('/')[1] $AWS_GroupID = Get-SwisData -SwisConnection $swis ` -Query "SELECT TOP 1 GroupId FROM IPAM.GroupNode where address = '$ip' and cidr = '$cidr' " if ($AWS_GroupID -eq $null) { "create $ip - $cdr " Invoke-SwisVerb $swis IPAM.SubnetManagement CreateSubnet @($ip, $cidr ) } #update properties # subnetID and URI are both IDs that refer to the same object $URI = Get-SwisData -SwisConnection $swis ` -Query "SELECT TOP 1 URI FROM IPAM.GroupNode where address = '$ip' and cidr = '$cidr' " $SubnetID = Get-SwisData -SwisConnection $swis ` -Query "SELECT TOP 1 GroupID FROM IPAM.GroupNode where address = '$ip' and cidr = '$cidr' " #disable auto scan # We do NOT want solarwinds ICMP scanning and changing the staus of things. Also means we # need to manage everything including (I think?) DNS and host data. Invoke-SwisVerb $swis IPAM.SubnetManagement ChangeDisableAutoScanning @( $SubnetID, "false") #set custom properties #not supported yet by API #Set-SwisObject $swis -Uri $URI -Properties @{Object_ID=$ff} #Set-SwisObject $swis -Uri $URI -Properties @{aws_cloudformation_logical_id=$ff} #Set-SwisObject $swis -Uri $URI -Properties @{aws_cloudformation_stack_id=$ff} #Set-SwisObject $swis -Uri $URI -Properties @{aws_cloudformation_stack_name=$ff} #Set-SwisObject $swis -Uri $URI -Properties @{OwnerId=$ff} $sql = " update [SolarWindsOrion].[dbo].[IPAM_GroupAttrData] SET [Object_ID] = '" + $vpc.vpcid + "' ,[aws_cloudformation_logical_id] = '"+ $vpc.'aws:cloudformation:logical-id' +"' ,[aws_cloudformation_stack_id] = '"+ $vpc.'aws:cloudformation:stack-id' +"' ,[aws_cloudformation_stack_name] = '"+ $vpc.'aws:cloudformation:stack-name' +"' ,[OwnerId] = '"+ $vpc.OwnerId +"' where groupid = $SubnetID" $rs = Invoke-Sqlcmd -ServerInstance $SQL_Server -Database SolarwindsOrion -Query $sql #set basic properties #note groupType=4 means supernet $sql = " update dbo.ipam_group SET parentid = $AWS_RootID ,FriendlyName = '" + $vpc.Name + "' + Address + ' /' + cast(CIDR as varchar(10)) ,GroupType = 4 where groupid = $SubnetID" $rs = Invoke-Sqlcmd -ServerInstance $SQL_Server -Database SolarwindsOrion -Query $sql } } } ####################################### 'start...' #initialise Solarwinds API # load the snappin if it's not already loaded (step 1) if (!(Get-PSSnapin | Where-Object { $_.Name -eq "SwisSnapin" })) { Add-PSSnapin "SwisSnapin" } $swis = Connect-Swis -Hostname $SW_Server -Trusted #check that IPAM group folder exists $AWS_RootID = Get-SwisData ` -SwisConnection $swis ` -Query "SELECT TOP 1 GroupId FROM IPAM.GroupNode where FriendlyName = '$AWS_GroupName'" if ( $AWS_GroupID -eq $null ){ 'exit bad!' exit } #initialise AWS API – and proxy access (if you use it) import-module AWSPowerShell.NetCore set-awsproxy -hostname “xxx” -port 9090 #this is the list of IAM roles/accounts. There must be a better way to get this info – instead of this manualy compiled list. $arnList = 'arn:aws:iam::999:role/role--monitoring', 'arn:aws:iam::993:role/role-monitoring', ` 'arn:aws:iam::991:role/role--monitoring', 'arn:aws:iam::992:role/role-monitoring' #account access key set-awscredential -accesskey 'xxxx' -secretkey yyyy' -StoreAs solar Initialize-AWSDefaults -ProfileName solar -Region ap-southeast-2 #build ARN list $creds = [System.Collections.ArrayList]@() foreach( $arn in $arnList ) { $arn $cr = $null $cr = (Use-STSRole -RoleArn $arn -RoleSessionName "solar").Credentials if ( $cr ) { $cr | add-member -NotePropertyName 'arn' -NotePropertyValue $arn $cr $creds.Add( $cr ) } } #loop through the creds array. Hit each account in turn foreach( $cred in $creds ){ #get all subnets in account. Will be children of the supernets $subn = Get-ec2subnet -Credential $Cred $subnets = @($subn | select-object AvailabilityZone, CidrBlock, State, SubnetId, VpcId, @{Name='Name'; Expression = { ($_.Tags | Where-Object {$_.Key -eq 'Name'}).Value }} ` ,@{Name='aws:cloudformation:logical-id'; Expression = { ($_.Tags | Where-Object {$_.Key -eq 'aws:cloudformation:logical-id'}).Value }} ` ,@{Name='aws:cloudformation:stack-id'; Expression = { ($_.Tags | Where-Object {$_.Key -eq 'aws:cloudformation:stack-id'}).Value }} ` ,@{Name='aws:cloudformation:stack-name'; Expression = { ($_.Tags | Where-Object {$_.Key -eq 'aws:cloudformation:stack-name'}).Value }} ) #get all VPCs in accounts. Will be supernets, and children of the main AWS folder (see variable at top of script) $vpc = Get-EC2Vpc -Credential $Cred $vpcs = @($vpc | select-object CidrBlock, OwnerId, VpcId, @{Name='Name'; Expression = { ($_.Tags | Where-Object {$_.Key -eq 'Name'}).Value }} ` ,@{Name='aws:cloudformation:logical-id'; Expression = { ($_.Tags | Where-Object {$_.Key -eq 'aws:cloudformation:logical-id'}).Value }} ` ,@{Name='aws:cloudformation:stack-id'; Expression = { ($_.Tags | Where-Object {$_.Key -eq 'aws:cloudformation:stack-id'}).Value }} ` ,@{Name='aws:cloudformation:stack-name'; Expression = { ($_.Tags | Where-Object {$_.Key -eq 'aws:cloudformation:stack-name'}).Value }} ) #TODO. Call Get-EC2Subnet for all IPs in use Upsert-AWS-VPC -vpcs $vpcs -swis $swis -AWS_RootID $AWS_RootID } Remove-AWSCredentialProfile -ProfileName solar