Here is an example Powershell script to extract data out of AWS CloudWatch using the AWS tool kit.
I needed to visualize this data outside of the AWS console… so I built this extractor to pull out metric data for different types of AWS objects, check out the example below.
<# AWS CloudWatch Metric Extractor , Requires Module --> https://github.com/dfinke/ImportExcel Collecting metric / state data from AWS CloudWatch api and output's to CSV, run the script without parameters for instructions. Script requires Powershell v3 and above. Run the command below to store AccessKey and SecretKey in secure credential XML for each environment $cred = Get-Credential $cred | Export-Clixml -Path "d:\AWS\config\us-east-1.xml" Run the command below to store user and password which will login to the internet proxy. $cred = Get-Credential $cred | Export-Clixml -Path "d:\AWS\config\proxy.xml" #> param ( [String]$CollectionType = 'Collection', [String]$AWSMetricNameSpace = 'AWS/EC2', [String]$AWSRegion = 'us-east-1', [Array]$InstanceById = @('i-BleBlahBlue','i-BleBlahRed'), [Array]$Metrics = @('CPUUtilization','DiskReadBytes','DiskReadOps','DiskWriteBytes','DiskWriteOps','NetworkIn','NetworkOut','NetworkPacketsIn','NetworkPacketsOut'), [String]$rollUpType = 'Average', [String]$intervalType = 3600, [DateTime]$StartDate = (Get-date).addDays(-2), [DateTime]$EndDate = (Get-date), [String]$Format = 'XLS', [String]$Email, [String]$FileName, # = 'MyBoxes', [String]$OutputLocation, # = 'd:\Watcher\WebSSO\us-east-1', [String]$InstanceByIdLookupList # = 'd:\Watcher\Servers.csv' ) #Params $ScriptPath = 'D:\Wacther' $LogFileLoc = $ScriptPath + '\Log\Logfile.log' $RunDateTime = (Get-date) $RunDateTime = $RunDateTime.tostring("yyyyMMddHHmmss") $StartDateFile = $StartDate.tostring("yyyyMMdd-HHmmss") $EndDateFile = $EndDate.tostring("yyyyMMdd-HHmmss") $Share = '\\localhost\completed\' $mailserver = 'mailserverbox.vMan.ch' $mailport = 25 $ProxyCreds = 'MeProxy' $ProxyHost = 'proxy.vMan.ch' $ProxyPort = 8080 #Functions #Logging Function Function Log([String]$message, [String]$LogType, [String]$LogFile){ $date = Get-Date -UFormat '%m-%d-%Y %H:%M:%S' $message = $date + "`t" + $LogType + "`t" + $message $message >> $LogFile } #Send Email Function Function SS64Mail($SMTPServer, $SMTPPort, $SMTPuser, $SMTPPass, $strSubject, $strBody, $strSenderemail, $strRecipientemail, $AttachFile) { [System.Net.ServicePointManager]::ServerCertificateValidationCallback = { return $true } $MailMessage = New-Object System.Net.Mail.MailMessage $SMTPClient = New-Object System.Net.Mail.smtpClient ($SMTPServer, $SMTPPort) $SMTPClient.EnableSsl = $true $SMTPClient.Credentials = New-Object System.Net.NetworkCredential($SMTPuser, $SMTPPass) $Recipient = New-Object System.Net.Mail.MailAddress($strRecipientemail, "Recipient") $Sender = New-Object System.Net.Mail.MailAddress($strSenderemail, "vMan AWS Metrics") $MailMessage.Sender = $Sender $MailMessage.From = $Sender $MailMessage.Subject = $strSubject $MailMessage.To.add($Recipient) $MailMessage.Body = $strBody if ($AttachFile -ne $null) {$MailMessage.attachments.add($AttachFile) } $SMTPClient.Send($MailMessage) } switch($CollectionType) { Collection { If ($InstanceByIdLookupList -gt ''){ Log -Message "Collecting $intervalType between $StartDateFile and $EndDateFile" -LogType "JOB-$RunDateTime" -LogFile $LogFileLoc echo "Collecting $intervalType between $StartDateFile and $EndDateFile" Log -Message "Collecting metrics: $Metrics" -LogType "JOB-$RunDateTime" -LogFile $LogFileLoc echo "Collecting metrics: $Metrics" Log -Message "Data collection for objects listed in the file $InstanceByIdLookupList" -LogType "JOB-$RunDateTime" -LogFile $LogFileLoc echo "Data collection for objects listed in the file $InstanceByIdLookupList" $InstanceById = '' [Array]$InstanceById = import-csv $InstanceByIdLookupList | where ENV -eq $AWSRegion | Select Server [Array]$InstanceById = $InstanceById.Server Log -Message "Data collection for $InstanceById" -LogType "JOB-$RunDateTime" -LogFile $LogFileLoc echo "Data collection for $InstanceById" } else { Log -Message "Collecting $intervalType between $StartDateFile and $EndDateFile" -LogType "JOB-$RunDateTime" -LogFile $LogFileLoc echo "Collecting $intervalType between $StartDateFile and $EndDateFile" Log -Message "Collecting metrics: $Metrics" -LogType "JOB-$RunDateTime" -LogFile $LogFileLoc echo "Collecting metrics: $Metrics" Log -Message "Data collection for object: $InstanceById" -LogType "JOB-$RunDateTime" -LogFile $LogFileLoc echo "Data collection for object: $InstanceById" } #Set's the AWS Region to query if($AWSRegion-gt ""){ Set-DefaultAWSRegion -Region $AWSRegion } else { echo "AWS region not specified, bye!!" Exit } #Sets the credentials to access the data. if($AWSRegion -gt ""){ $AWSCred = Import-Clixml -Path "$ScriptPath\config\$AWSRegion.xml" $AWSUser = $AWSCred.GetNetworkCredential().Username $AWSPassword = $AWSCred.GetNetworkCredential().Password Set-AWSCredentials -AccessKey $AWSUser -SecretKey $AWSPassword } else { Log -Message "AWS credentials not specified, bye!!" -LogType "JOB-$RunDateTime" -LogFile $LogFileLoc echo "AWS credentials not specified, bye!!" Exit } #Check if any metrics specified if($Metrics -eq ""){ echo "No metrics specified, bye!!" Exit } #Set the Internet Proxy if you cant get out directly the to net. if($ProxyCreds -gt ""){ $ProxyCred = Import-Clixml -Path "$ScriptPath\config\$ProxyCreds.xml" $ProxyUser = $ProxyCred.GetNetworkCredential().Username $ProxyPassword = $ProxyCred.GetNetworkCredential().Password Set-AWSProxy -Hostname $ProxyHost -Port $ProxyPort -Password $ProxyPassword -Username $ProxyUser } else { Log -Message "Proxy credentials not specified so not configuring proxy" -LogType "JOB-$RunDateTime" -LogFile $LogFileLoc echo "Proxy credentials not specified so not configuring proxy" } if($Email -imatch '^.*@vMan\.ch Hope this was helpful vMAN ){ Log -Message "$email matches the vMan.ch domain" -LogType "JOB-$RunDateTime" -LogFile $LogFileLoc Echo "$email matches the vMan.ch domain" $SMTPcred = Import-Clixml -Path "$ScriptPath\config\smtp.xml" $SMTPUser = $SMTPcred.GetNetworkCredential().Username $SMTPPassword = $SMTPcred.GetNetworkCredential().Password } else { Log -Message "$email is not in the vMan.ch domain, will not send mail but report generation will continue" -LogType "JOB-$RunDateTime" -LogFile $LogFileLoc Echo "$email is not in the vMan.ch domain, will not send mail but report generation will continue" $Email = '' } $report = @() ForEach ($InstanceID in $InstanceById){ echo "Running collection for instance: $InstanceID" Log -Message "Running collection for instance: $InstanceID" -LogType "JOB-$RunDateTime" -LogFile $LogFileLoc Get-Date -UFormat '%m-%d-%Y %H:%M:%S' $dimension = New-Object Amazon.CloudWatch.Model.Dimension $dimension.set_Name('InstanceId') $dimension.set_Value($InstanceID) ForEach ($Metric in $Metrics){ $Data = @() echo "Collecting Metric $Metric for $InstanceID" Log -Message "Collecting Metric $Metric for $InstanceID" -LogType "JOB-$RunDateTime" -LogFile $LogFileLoc Get-Date -UFormat '%m-%d-%Y %H:%M:%S' $Data = Get-CWMetricStatistics -Namespace $AWSMetricNameSpace -dimension $dimension -MetricName $Metric -StartTime $StartDate -EndTime $EndDate -Period $intervalType -Statistics $rollUpType echo "Transforming Metric $Metric for $InstanceID" Log -Message "Transforming Metric $Metric for $InstanceID" -LogType "JOB-$RunDateTime" -LogFile $LogFileLoc Get-Date -UFormat '%m-%d-%Y %H:%M:%S' If ($rollUpType -eq 'Average') {$values = @($Data.DataPoints.Average)} If ($rollUpType -eq 'Maximum') {$values = @($Data.DataPoints.Maximum)} If ($rollUpType -eq 'Minumum') {$values = @($Data.DataPoints.Minumum)} $Timestamps = @($Data.DataPoints.timestamp) for ($i=0; $i -lt $Values.Count -and $i -lt $Timestamps.Count; $i++) { $report += New-Object PSObject -Property @{ Metric = $Metric InstanceId = $InstanceID Timestamp = $Timestamps[$i] value = $values[$i] } } } } #Output merge to Excel if ($Format -eq 'XLS'){ Get-Date -UFormat '%m-%d-%Y %H:%M:%S' echo 'Generate XLS' Log -Message "Generate XLS" -LogType "JOB-$RunDateTime" -LogFile $LogFileLoc If ($FileName -gt ''){ $OutputExcelFile = $OutputLocation + $FileName + '.xlsx' $ShareExcelFile = $OutputLocation + $FileName + '.xlsx' remove-item $OutputExcelFile -Force -ErrorAction SilentlyContinue -Recurse } else { $OutputExcelFile = $ScriptPath + '\completed\Collected_Metrics_' + $intervalType + '_' + [String]$rollUpType + '_' + [String]$StartDateFile + '_' + [String]$EndDateFile + '_' + $RunDateTime + '.xlsx' $ShareExcelFile = $share + 'Collected_Metrics_' + $intervalType + '_' + [String]$rollUpType + '_' + [String]$StartDateFile + '_' + [String]$EndDateFile + '_' + $RunDateTime + '.xlsx' } $report | select Timestamp,InstanceId,Metric,value | Sort-Object { $_.Timestamp -as [datetime] } | Export-Excel $OutputExcelFile -WorkSheetname Data -ChartType Line -IncludePivotChart -IncludePivotTable -PivotRows Timestamp -PivotData value -PivotColumns InstanceId,Metric Log -Message "Task complete, pickup your file from the share $ShareExcelFile within the next 24 hours as it will be automatically deleted" -LogType "JOB-$RunDateTime" -LogFile $LogFileLoc Echo "Task complete, pickup your file from the share $ShareExcelFile within the next 24 hours as it will be automatically deleted" if($Email -gt "") { Log -Message "Email found and is vMan.ch domain, sending report to $email" -LogType "JOB-$RunDateTime" -LogFile $LogFileLoc Echo "Email found and is vMan.ch domain, sending email to $email" SS64Mail $mailserver $mailport $SMTPUser $SMTPPassword "ENV $creds Report started at $RunDateTime complete" "Your report should be attached, if it's missing it was probably too large to send via the mail server.... Pickup it up from here $ShareExcelFile within the next 24H" 'info@vman.ch' $email $OutputExcelFile Log -Message "Email sent to $email" -LogType "JOB-$RunDateTime" -LogFile $LogFileLoc Echo "Email sent to $email" } Get-Date -UFormat '%m-%d-%Y %H:%M:%S' echo 'All done, Terminating Script' Log -Message "All done, Terminating Script" -LogType "JOB-$RunDateTime" -LogFile $LogFileLoc Remove-Variable * -Force -ErrorAction SilentlyContinue Exit } #Output to CSV if ($Format -eq 'CSV'){ Get-Date -UFormat '%m-%d-%Y %H:%M:%S' echo 'Generate CSV' Log -Message "Generate CSV" -LogType "JOB-$RunDateTime" -LogFile $LogFileLoc If ($FileName -gt ''){ $OutputCSVFile = $OutputLocation + $FileName + '.csv' $ShareCSVFile = $OutputLocation + $FileName + '.csv' } else { $OutputCSVFile = $ScriptPath + '\completed\Collected_Metrics_' + $intervalType + '_' + [String]$rollUpType + '_' + [String]$StartDateFile + '_' + [String]$EndDateFile + '_' + $RunDateTime + '.csv' $ShareCSVFile = $share + 'Collected_Metrics_' + $intervalType + '_' + [String]$rollUpType + '_' + [String]$StartDateFile + '_' + [String]$EndDateFile + '_' + $RunDateTime + '.csv' } $report | select Timestamp,InstanceId,Metric,value | Sort-Object { $_.Timestamp -as [datetime] } | Export-csv $OutputCSVFile -NoTypeInformation Log -Message "Task complete, pickup your file from the share $ShareCSVFile within the next 24 hours as it will be automatically deleted" -LogType "JOB-$RunDateTime" -LogFile $LogFileLoc Echo "Task complete, pickup your file from the share $ShareCSVFile within the next 24 hours as it will be automatically deleted" if($Email -gt "") { Log -Message "Email found and is vMan.ch domain, sending CSV link to $email" -LogType "JOB-$RunDateTime" -LogFile $LogFileLoc Echo "Email found and is vMan.ch domain, sending CSV link to $email" SS64Mail $mailserver $mailport $SMTPUser $SMTPPassword "ENV $creds Report started at $RunDateTime complete" "Your report is ready, Pickup it up from here $ShareCSVFile within the next 24H" 'info@vman.ch' $email Log -Message "Email sent to $email" -LogType "JOB-$RunDateTime" -LogFile $LogFileLoc Echo "Email sent to $email" } Get-Date -UFormat '%m-%d-%Y %H:%M:%S' echo 'All done, Terminating Script' Log -Message "All done, Terminating Script" -LogType "JOB-$RunDateTime" -LogFile $LogFileLoc Remove-Variable * -Force -ErrorAction SilentlyContinue Exit } } <# #Debug, get list of Metrics #$AWSCW = Get-CWMetrics #> default{"Usage The script can be run by specifying all parameters otherwise it will use some default values. .\CloudWatcher.ps1 -CollectionType 'Collection' -AWSRegion 'us-east-1' -StartDate '2016/09/16 10:00' -EndDate '2016/09/16 11:00' -Metrics 'CPUUtilization','DiskReadBytes','DiskReadOps','DiskWriteBytes','DiskWriteOps','NetworkIn','NetworkOut','NetworkPacketsIn','NetworkPacketsOut' -rollUpType 'Average' -intervalType '3600' -Format 'XLS' -FileName 'MyBoxes' -OutputLocation 'D:\Watcher\' -InstanceByIdLookupList 'D:\Watcher\Servers.csv' "} }
Hope this was helpful
vMAN
Recent Comments