AzureIPAddress.ps1
<#PSScriptInfo .VERSION 1.0 .GUID bc41499f-a9d2-4329-9110-d049984143c1 .AUTHOR timmcmic .COMPANYNAME .COPYRIGHT .TAGS .LICENSEURI .PROJECTURI .ICONURI .EXTERNALMODULEDEPENDENCIES .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES .PRIVATEDATA #> <# .DESCRIPTION This script allows scanning of azure ip address spaces for an azure ip. #> Param( [Parameter(Mandatory = $false)] [string]$IPAddressToTest="0.0.0.0", [Parameter(Mandatory = $true)] [string]$logFolderPath=$NULL ) $ErrorActionPreference = 'Stop' #------------------------------------------------------------------------------- Function new-LogFile { [cmdletbinding()] Param ( [Parameter(Mandatory = $true)] [string]$logFileName, [Parameter(Mandatory = $true)] [string]$logFolderPath ) [string]$logFileSuffix=".log" [string]$fileName=$logFileName+$logFileSuffix # Get our log file path $logFolderPath = $logFolderPath+"\"+$logFileName+"\" #Since $logFile is defined in the calling function - this sets the log file name for the entire script $global:LogFile = Join-path $logFolderPath $fileName #Test the path to see if this exists if not create. [boolean]$pathExists = Test-Path -Path $logFolderPath if ($pathExists -eq $false) { try { #Path did not exist - Creating New-Item -Path $logFolderPath -Type Directory } catch { throw $_ } } } #------------------------------------------------------------------------------- Function Out-LogFile { [cmdletbinding()] Param ( [Parameter(Mandatory = $true)] $String, [Parameter(Mandatory = $false)] [boolean]$isError=$FALSE ) # Get the current date [string]$date = Get-Date -Format G # Build output string #In this case since I abuse the function to write data to screen and record it in log file #If the input is not a string type do not time it just throw it to the log. if ($string.gettype().name -eq "String") { [string]$logstring = ( "[" + $date + "] - " + $string) } else { $logString = $String } # Write everything to our log file and the screen $logstring | Out-File -FilePath $global:LogFile -Append #Write to the screen the information passed to the log. if ($string.gettype().name -eq "String") { Write-Host $logString } else { write-host $logString | select-object -expandProperty * } #If the output to the log is terminating exception - throw the same string. if ($isError -eq $TRUE) { #Ok - so here's the deal. #By default error action is continue. IN all my function calls I use STOP for the most part. #In this case if we hit this error code - one of two things happen. #If the call is from another function that is not in a do while - the error is logged and we continue with exiting. #If the call is from a function in a do while - write-error rethrows the exception. The exception is caught by the caller where a retry occurs. #This is how we end up logging an error then looping back around. write-error $logString #Now if we're not in a do while we end up here -> go ahead and create the status file this was not a retryable operation and is a hard failure. exit } } #------------------------------------------------------------------------------- #Following function credit to author -> https://github.com/fleschutz/PowerShell/blob/main/docs/check-ipv4-address.md function IsIPv4AddressValid { param([string]$IP) $RegEx = "^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$" if ($IP -match $RegEx) { return $true } else { return $false } } #------------------------------------------------------------------------------- #Follwoing function credit to author -> https://github.com/fleschutz/PowerShell/blob/main/docs/check-ipv6-address.md function IsIPv6AddressValid { param([string]$IP) $IPv4Regex = '(((25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})\.){3}(25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2}))' $G = '[a-f\d]{1,4}' $Tail = @(":", "(:($G)?|$IPv4Regex)", ":($IPv4Regex|$G(:$G)?|)", "(:$IPv4Regex|:$G(:$IPv4Regex|(:$G){0,2})|:)", "((:$G){0,2}(:$IPv4Regex|(:$G){1,2})|:)", "((:$G){0,3}(:$IPv4Regex|(:$G){1,2})|:)", "((:$G){0,4}(:$IPv4Regex|(:$G){1,2})|:)") [string] $IPv6RegexString = $G $Tail | foreach { $IPv6RegexString = "${G}:($IPv6RegexString|$_)" } $IPv6RegexString = ":(:$G){0,5}((:$G){1,2}|:$IPv4Regex)|$IPv6RegexString" $IPv6RegexString = $IPv6RegexString -replace '\(' , '(?:' # make all groups non-capturing [regex] $IPv6Regex = $IPv6RegexString if ($IP -imatch "^$IPv6Regex$") { return $true } else { return $false } } #------------------------------------------------------------------------------- Function Test-PowershellVersion { [cmdletbinding()] $functionPowerShellVersion = $NULL Out-LogFile -string "********************************************************************************" Out-LogFile -string "BEGIN TEST-POWERSHELLVERSION" Out-LogFile -string "********************************************************************************" #Write function parameter information and variables to a log file. $functionPowerShellVersion = $PSVersionTable.PSVersion out-logfile -string "Determining powershell version." out-logfile -string ("Major: "+$functionPowerShellVersion.major) out-logfile -string ("Minor: "+$functionPowerShellVersion.minor) out-logfile -string ("Patch: "+$functionPowerShellVersion.patch) out-logfile -string $functionPowerShellVersion if ($functionPowerShellVersion.Major -ge 7) { out-logfile -string "Powershell 7 and higher is currently not supported due to module compatibility issues." out-logfile -string "Please run module from Powershell 5.x" out-logfile -string "" -isError:$true } else { out-logfile -string "Powershell version is not powershell 7.1 proceed." } Out-LogFile -string "********************************************************************************" Out-LogFile -string "END TEST-POWERSHELLVERSION" Out-LogFile -string "********************************************************************************" } #------------------------------------------------------------------------------- function get-AzureHTMLData { param( [Parameter(Mandatory = $true)] $azureCloudLocation ) $functionHTMLData = $null out-logfile -string "Starting get-AzureHTMLData" try { out-logfile -string "Invoking web request to obtain html data." $functionHTMLData = invoke-webRequest -Uri $azureCloudLocation -errorAction Stop out-logfile -string "Web data successfully retrieved." } catch { out-logfile -string "Unable to obtain azure html data." out-logfile -string $_ -isError:$true } out-logFile -string "Ending get-AzureHTMLData" return $functionHTMLData } #------------------------------------------------------------------------------- function get-AzureDownloadLink { param( [Parameter(Mandatory = $true)] $azureCloudLocation ) $functionDownloadLink = $NULL $functionLinkString = "click here to download manually" out-logfile -string "Starting get-AzureDownloadLink" $functionDownloadLink = $azureCloudLocation.links | where-object {$_.InnerText -eq $functionLinkString} out-logfile -string $functionDownloadLink $functionDownLoadLink = $functionDownLoadLink.href out-logfile -string $functionDownLoadLink out-logfile -string "Ending get-AzureDownloadLink" return $functionDownloadLink } #------------------------------------------------------------------------------- function get-AzureJSONData { param( [Parameter(Mandatory = $true)] $azureCloudLocation ) $functionAzureJSONData = $NULL out-logfile -string "Starting get-AzureJSONData" try { out-logfile -string "Invoking web request to obtain json data..." $functionAzureJSONData = invoke-webRequest -uri $azureCloudLocation -errorAction STOP out-logfile -string "Web request to obtain json data successful." } catch { out-logfile -string "Unable to invoke web request to obtain json data." out-logfile -string $_ -isError:$TRUE } out-logfile -string "Converting downloaded data to powershell json format." try { $functionAzureJsonData = convertFrom-Json $functionAzureJsonData -errorAction STOP } catch { out-logfile -string "Unable to convert data to json format." out-logfile -string $_ -isError:$TRUE } out-logfile -string "Ending get-AzureJSONData" return $functionAzureJsonData } #------------------------------------------------------------------------------- function export-AzureJSONData { param( [Parameter(Mandatory = $true)] $exportLocation, [Parameter(Mandatory = $true)] $jsonData ) $functionAzureJSONData = $NULL out-logfile -string "Starting export-AzureJSONData" try { $jsonData | export-clixml $exportLocation } catch { out-logfile -string "Unable to export the json data." out-logfile -string $_ -isError:$TRUE } out-logfile -string "Ending export-AzureJSONData" } #------------------------------------------------------------------------------- #******************************************************************************* #Begin main script function #******************************************************************************* #Define function specific variables. [string]$noIPSpecified = "0.0.0.0" [string]$logFileName = "" [string]$staticLogFileName = "AzureIPAddress" [string]$azureIPInformationPublicCloud = "https://www.microsoft.com/en-us/download/confirmation.aspx?id=56519" [string]$azureIPInformationGovernmentCloud = "https://www.microsoft.com/en-us/download/confirmation.aspx?id=57063" $azurePublicCloudHTMLData = $null $azureGovernmentCloudHTMLData = $null $azurePublicCloudDownloadLink = $null $azureGovernmentCloudDownloadLink = $null $azurePublicCloudJSONData = $NULL $azureGovernmentCloudJSONData = $null $azurePublicJSONExport = $global:logFile.replace(".log","-Public.xml") $azureGovernmentJSONExport = $global:logFile.replace(".log","-Government.xml") #Define the log file name if ($IPAddressToTest -ne $noIPSpecified) { write-host "IP Address specified - utlize this as the log file name." if ($IPAddressToTest.contains(".")) { $logFileName = $IPAddressToTest.replace(".","-") if (IsIPv4AddressValid -ip $ipAddressToTest) { write-host "IPv4 Address is in a valid format." } else { write-error "IPv4 address specified and is not in a valid format." } } else { $logFileName = $IPAddressToTest.replace(":","-") if (IsIPv6AddressValid -ip $ipAddressToTest) { write-host "IPv6 address specified and is in proper format." } else { write-error "IPv6 address specified and is not in a valid format." } } } else { write-error "You forgot to specify an ip address to test." } new-logfile -logFileName $logFileName -logFolderPath $logFolderPath out-logfile -string "*************************************************************" out-logfile -string "Starting AzureIPAddress.ps1" out-logfile -string "*************************************************************" out-logfile -string "Testing Powershell Version - 5.x required..." Test-PowershellVersion out-logfile -string "Obtaining the azure html data." $azurePublicCloudHTMLData = get-AzureHTMLData -azureCloudLocation $azureIPInformationPublicCloud $azureGovernmentCloudHTMLData = get-azureHTMLData -azureCloudLocation $azureIPInformationGovernmentCloud out-logfile -string "Obtaining data download link..." $azurePublicCloudDownloadLink = get-AzureDownloadLink -azureCloudLocation $azurePublicCloudHTMLData $azureGovernmentCloudDownloadLink = get-AzureDownloadLink -azureCloudLocation $azureGovernmentCloudHTMLData out-logfile -string "Obtaining json data..." $azurePublicCloudJSONData = get-azureJSONData -azureCloudLocation $azurePublicCloudDownloadLink $azureGovernmentCloudJSONData = get-azureJSONData -azureCloudLocation $azureGovernmentCloudDownloadLink out-logfile -string "Export the JSON data to the logging directory." export-AzureJSONData -exportLocation $azurePublicJSONExport -jsonData $azurePublicCloudJSONData export-AzureJSONData -exportLocation $azureGovernmentJSONExport -jsonData $azureGovernmentCloudJSONData out-logfile -string "Gather Azure IP information completed - the xml files may now be utilized for analysis." |