WapTenantPublicAPI.psm1
try { Add-Type -AssemblyName 'System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' Add-Type -AssemblyName 'System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' } catch { throw $_ } function IgnoreSSL { $Provider = New-Object Microsoft.CSharp.CSharpCodeProvider $Compiler= $Provider.CreateCompiler() $Params = New-Object System.CodeDom.Compiler.CompilerParameters $Params.GenerateExecutable = $False $Params.GenerateInMemory = $True $Params.IncludeDebugInformation = $False $Params.ReferencedAssemblies.Add('System.DLL') > $null $TASource=@' namespace Local.ToolkitExtensions.Net.CertificatePolicy { public class TrustAll : System.Net.ICertificatePolicy { public TrustAll() {} public bool CheckValidationResult(System.Net.ServicePoint sp,System.Security.Cryptography.X509Certificates.X509Certificate cert, System.Net.WebRequest req, int problem) { return true; } } } '@ $TAResults=$Provider.CompileAssemblyFromSource($Params,$TASource) $TAAssembly=$TAResults.CompiledAssembly ## We create an instance of TrustAll and attach it to the ServicePointManager $TrustAll = $TAAssembly.CreateInstance('Local.ToolkitExtensions.Net.CertificatePolicy.TrustAll') [System.Net.ServicePointManager]::CertificatePolicy = $TrustAll } function TestJWTClaimNotExpired { param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [ValidateScript({if ($_.split('.').count -eq 3) {$true}})] [String] $Token ) #based on functions by Shriram MSFT found on technet: https://gallery.technet.microsoft.com/JWT-Token-Decode-637cf001 process { try { $TokenData = $token.Split('.')[1] |%{ $data = $_ -as [String] $data = $data.Replace('-', '+').Replace('_', '/') switch ($data.Length % 4) { 0 { break } 2 { $data += '==' } 3 { $data += '=' } default { throw New-Object ArgumentException('data') } } [System.Text.Encoding]::UTF8.GetString([convert]::FromBase64String($data)) | ConvertFrom-Json } #JWT Reference Time $Ref = [datetime]::SpecifyKind((New-Object -TypeName datetime ('1970',1,1,0,0,0)),'UTC') #UTC time right now - Reference time gives amount of seconds to check against $CheckSeconds = [System.Math]::Round(([datetime]::UtcNow - $Ref).totalseconds) if ($TokenData.exp -gt $CheckSeconds) { Write-Output -InputObject $true } else { Write-Output -InputObject $false } } catch { throw $_ } } } function Get-WAPToken { <# .SYNOPSIS Retrieves a Bearer token from either ADFS or the WAP ASP.Net STS. .PARAMETER Url The URL of either the ADFS or WAP STS. .PARAMETER Port The Port on which ADFS or WAP STS is listening. Default for ADFS is 443, for WAP STS 30071. .PARAMETER ClientRealm The realm name of either the TenantSite (default) or AdminSite. .PARAMETER Credential Credentials to acquire the bearer token. .PARAMETER ADFS When enabled the token will be requested from an ADFS STS. When disabled the WAP STS is assumed. .PARAMETER IgnoreSSL When using self-signed certificates, SSL validation will be ignored when this switch is enabled. .EXAMPLE PS C:\>$URL = 'https://publictenantapi.mydomain.com' PS C:\>$creds = Get-Credential PS C:\>$token = Get-WAPToken -Credential $creds -URL 'https://sts.adfs.com' -ADFS This will return a bearer token from ADFS STS. .EXAMPLE PS C:\>$URL = 'https://publictenantapi.mydomain.com' PS C:\>$creds = Get-Credential PS C:\>$token = Get-WAPToken -Credential $creds -URL 'https://sts.wap.com' -Port 443 This will return a bearer token from WAP STS using the non default port 443. #> [cmdletbinding()] param ( [Parameter(Mandatory)] [string]$URL, [int] $Port, [ValidateSet('http://azureservices/AdminSite','http://azureservices/TenantSite')] [String] $ClientRealm = 'http://azureservices/TenantSite', [Parameter(Mandatory)] [PSCredential] $Credential, [Switch] $ADFS, [Switch] $IgnoreSSL ) try { if ($ADFS -and $Port -eq 0) { $Port = 443 } elseif ($Port -eq 0 -and $clientRealm -eq 'http://azureservices/TenantSite') { $Port = 30071 } elseif ($Port -eq 0 -and $clientRealm -eq 'http://azureservices/AdminSite') { $Port = 30072 } if ($ADFS) { Write-Verbose -Message 'Constructing ADFS URL' $ConstructedURL = $URL + ":$Port" + '/adfs/services/trust/13/usernamemixed' } else { Write-Verbose -Message 'Constructing ASPNet URL' $ConstructedURL = $URL + ":$Port" + '/wstrust/issue/usernamemixed' } Write-Verbose -Message $ConstructedURL $identityProviderEndpoint = New-Object -TypeName System.ServiceModel.EndpointAddress -ArgumentList $ConstructedURL $identityProviderBinding = New-Object -TypeName System.ServiceModel.WS2007HttpBinding -ArgumentList ([System.ServiceModel.SecurityMode]::TransportWithMessageCredential) $identityProviderBinding.Security.Message.EstablishSecurityContext = $false $identityProviderBinding.Security.Message.ClientCredentialType = 'UserName' $identityProviderBinding.Security.Transport.ClientCredentialType = 'None' $trustChannelFactory = New-Object -TypeName System.ServiceModel.Security.WSTrustChannelFactory -ArgumentList $identityProviderBinding, $identityProviderEndpoint $trustChannelFactory.TrustVersion = [System.ServiceModel.Security.TrustVersion]::WSTrust13 if ($IgnoreSSL) { Write-Warning -Message 'IgnoreSSL switch defined. Certificate errors will be ignored!' $certificateAuthentication = New-Object -TypeName System.ServiceModel.Security.X509ServiceCertificateAuthentication $certificateAuthentication.CertificateValidationMode = 'None' $trustChannelFactory.Credentials.ServiceCertificate.SslCertificateAuthentication = $certificateAuthentication } if ($ADFS) { $ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToCoTaskMemUnicode($credential.Password) $password = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($ptr) [System.Runtime.InteropServices.Marshal]::ZeroFreeCoTaskMemUnicode($ptr) } $trustChannelFactory.Credentials.SupportInteractive = $false $trustChannelFactory.Credentials.UserName.UserName = $credential.UserName $trustChannelFactory.Credentials.UserName.Password = $credential.GetNetworkCredential().Password $rst = New-Object -TypeName System.IdentityModel.Protocols.WSTrust.RequestSecurityToken -ArgumentList ([System.IdentityModel.Protocols.WSTrust.RequestTypes]::Issue) $rst.AppliesTo = New-Object -TypeName System.IdentityModel.Protocols.WSTrust.EndpointReference -ArgumentList $clientRealm $rst.TokenType = 'urn:ietf:params:oauth:token-type:jwt' $rst.KeyType = [System.IdentityModel.Protocols.WSTrust.KeyTypes]::Bearer $rstr = New-Object -TypeName System.IdentityModel.Protocols.WSTrust.RequestSecurityTokenResponse $channel = $trustChannelFactory.CreateChannel() $token = $channel.Issue($rst, [ref] $rstr) $tokenString = ([System.IdentityModel.Tokens.GenericXmlSecurityToken]$token).TokenXml.InnerText; $token = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($tokenString)) Write-Output -InputObject $token } catch { throw $_ } } function Get-WAPSubscription { <# .SYNOPSIS Retrieves Tenant User Subscription from Azure Pack TenantPublic or Tenant API. .PARAMETER Token Bearer Token acquired via Get-WAPToken. .PARAMETER UserId The UserId used to get the Bearer token. .PARAMETER PublicTenantAPIUrl The URL of either the TenantPublic API or Tenant API. .PARAMETER Port The Port where the TenantPublic (30006) or Tenant API (30005) is listening on. Defaults to 30006. .PARAMETER Name The Name of the subscription to be acquired. .PARAMETER Id The Id of the subscription to be acquired. .PARAMETER List A list of all subscriptions the user has access to. .PARAMETER IgnoreSSL When using self-signed certificates, SSL validation will be ignored when this switch is enabled. .EXAMPLE PS C:\>$URL = 'https://publictenantapi.mydomain.com' PS C:\>$creds = Get-Credential PS C:\>$token = Get-WAPToken -Credential $creds -URL 'https://sts.adfs.com' -ADFS PS C:\>Get-WAPSubscription -Token $token -UserId $creds.UserName -PublicTenantAPIUrl $URL -Port 443 -Name 'MySubscription' This will return the subscription with name 'MySubscription' if it exists. .EXAMPLE PS C:\>$URL = 'https://publictenantapi.mydomain.com' PS C:\>$creds = Get-Credential PS C:\>$token = Get-WAPToken -Credential $creds -URL 'https://sts.wap.com' PS C:\>Get-WAPSubscription -Token $token -UserId $creds.UserName -PublicTenantAPIUrl $URL This will return a list of the users subscriptions using the default public tenant api port 30006. #> [CmdletBinding(DefaultParameterSetName='List')] param ( [Parameter(Mandatory)] [String] $Token, [Parameter(Mandatory)] [String] $UserId, [Parameter(Mandatory)] [String] $PublicTenantAPIUrl, [Int] $Port = 30006, [Parameter(Mandatory, ParameterSetName='Name')] [String] $Name, [Parameter(Mandatory, ParameterSetName='Id')] [String] $Id, [Parameter(ParameterSetName='List')] [Switch] $List, [Switch] $IgnoreSSL ) try { if ($IgnoreSSL) { Write-Warning 'IgnoreSSL switch defined. Certificate errors will be ignored!' #Change Certificate Policy to ignore $OriginalCertificatePolicy = [System.Net.ServicePointManager]::CertificatePolicy IgnoreSSL } Write-Verbose 'Validating Token not expired' if (!(TestJWTClaimNotExpired -Token $Token)) { throw 'Token has expired, fetch a new one!' } Write-Verbose 'Constructing Header' $Headers = @{ Authorization = "Bearer $Token" 'x-ms-principal-id' = $UserId Accept = 'application/json' } $Headers | Out-String | Write-Debug $URL = '{0}:{1}/subscriptions/' -f $PublicTenantAPIUrl,$Port Write-Verbose "Constructed Subscription URL: $URL" $Subscriptions = Invoke-RestMethod -Uri $URL -Headers $Headers -Method Get [void] $PSBoundParameters.Remove('Name') [void] $PSBoundParameters.Remove('Id') [void] $PSBoundParameters.Remove('List') foreach ($S in $Subscriptions) { if ($PSCmdlet.ParameterSetName -eq 'Name' -and $S.SubscriptionName -ne $Name) { continue } if ($PSCmdlet.ParameterSetName -eq 'Id' -and $S.SubscriptionId -ne $Id) { continue } $PSBoundParameters.GetEnumerator() | %{ Add-Member -InputObject $S -MemberType NoteProperty -Name $_.Key -Value $_.Value } $S.Created = [datetime]$S.Created Add-Member -InputObject $S -MemberType AliasProperty -Name 'Subscription' -Value SubscriptionId $S.PSObject.TypeNames.Insert(0,'WAP.Subscription') Write-Output -InputObject $S } } catch { throw $_ } finally { #Change Certificate Policy to the original if ($IgnoreSSL) { [System.Net.ServicePointManager]::CertificatePolicy = $OriginalCertificatePolicy } } } function Get-WAPGalleryVMRole { <# .SYNOPSIS Retrieves VM Role Gallery Items asigned to Tenant user Subscription from Azure Pack TenantPublic or Tenant API. .PARAMETER Token Bearer Token acquired via Get-WAPToken. .PARAMETER UserId The UserId used to get the Bearer token. .PARAMETER PublicTenantAPIUrl The URL of either the TenantPublic API or Tenant API. .PARAMETER Port The Port where the TenantPublic (30006) or Tenant API (30005) is listening on. Defaults to 30006. .PARAMETER Subscription The subscription id to get the VM Role Gallery Item from. .PARAMETER List Defaults to list mode. Shows all VM Role Gallery Items. .PARAMETER Name When Name is specified, only the VM Role Gallery Item with the specified name is returned. .PARAMETER IgnoreSSL When using self-signed certificates, SSL validation will be ignored when this switch is enabled. .EXAMPLE PS C:\>$URL = 'https://publictenantapi.mydomain.com' PS C:\>$creds = Get-Credential PS C:\>$token = Get-WAPToken -Credential $creds -URL 'https://sts.adfs.com' -ADFS PS C:\>$Subscription = Get-WAPSubscription -Token $token -UserId $creds.UserName -PublicTenantAPIUrl $URL -Port 443 -Name 'MySubscription' PS C:\>$Subscription | Get-WAPGalleryVMRole This will retrieve all VM Role Gallery Items tight to the subscription. .EXAMPLE PS C:\>$URL = 'https://publictenantapi.mydomain.com' PS C:\>$creds = Get-Credential PS C:\>$token = Get-WAPToken -Credential $creds -URL 'https://sts.adfs.com' -ADFS PS C:\>$Subscription = Get-WAPSubscription -Token $token -UserId $creds.UserName -PublicTenantAPIUrl $URL -Port 443 -Name 'MySubscription' PS C:\>$Subscription | Get-WAPGalleryVMRole -Name 'MyAwesomeVMRole' This will retreive only the VM Role Gallery Item with the same name as specified. .EXAMPLE PS C:\>$URL = 'https://publictenantapi.mydomain.com' PS C:\>$creds = Get-Credential PS C:\>$token = Get-WAPToken -Credential $creds -URL 'https://sts.adfs.com' -ADFS PS C:\>Get-WAPGalleryVMRole -Token $token -UserId $creds.UserName -PublicTenantAPIUrl $URL -Port 443 -SubscriptionId 'b5a9b263-066b-4a8f-87b4-1b7c90a5bcad' This will not make use of a subscription object but is entirely specified. All VM Role Gallery Items assigned to this subscription will be returned. #> [CmdletBinding(DefaultParameterSetName='List')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [String] $Token, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [String] $UserId, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [String] $PublicTenantAPIUrl, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [Alias('SubscriptionID')] [String] $Subscription, [Parameter(ValueFromPipelineByPropertyName)] [Int] $Port = 30006, [Parameter(ParameterSetName='List')] [Switch] $List, [Parameter(Mandatory, ParameterSetName='Name')] [String] $Name, [Switch] $IgnoreSSL ) process { try { if ($IgnoreSSL) { Write-Warning 'IgnoreSSL switch defined. Certificate errors will be ignored!' #Change Certificate Policy to ignore $OriginalCertificatePolicy = [System.Net.ServicePointManager]::CertificatePolicy IgnoreSSL } Write-Verbose 'Validating Token not expired' if (!(TestJWTClaimNotExpired -Token $Token)) { throw 'Token has expired, fetch a new one!' } Write-Verbose 'Constructing Header' $Headers = @{ Authorization = "Bearer $Token" 'x-ms-principal-id' = $UserId Accept = 'application/json' } $Headers | Out-String | Write-Debug $URI = '{0}:{1}/{2}/Gallery/GalleryItems/$/MicrosoftCompute.VMRoleGalleryItem?api-version=2013-03' -f $PublicTenantAPIUrl,$Port,$Subscription Write-Verbose "Constructed Gallery Item URI: $URI" $GalleryItems = Invoke-RestMethod -Uri $URI -Headers $Headers -Method Get [void] $PSBoundParameters.Remove('Name') [void] $PSBoundParameters.Remove('List') [void] $PSBoundParameters.Remove('IgnoreSSL') foreach ($G in $GalleryItems.value) { if ($PSCmdlet.ParameterSetName -eq 'Name' -and $G.Name -ne $Name) { continue } $PSBoundParameters.GetEnumerator() | %{ Add-Member -InputObject $G -MemberType NoteProperty -Name $_.Key -Value $_.Value } $GIResDEFUri = '{0}:{1}/{2}/{3}/?api-version=2013-03' -f $PublicTenantAPIUrl,$Port,$Subscription,$G.ResourceDefinitionUrl Write-Verbose -Message "Acquiring ResDef from URI: $GIResDEFUri" $ResDef = Invoke-RestMethod -Uri $GIResDEFUri -Headers $Headers -Method Get $GIViewDefUri = '{0}:{1}/{2}/{3}/?api-version=2013-03' -f $PublicTenantAPIUrl,$Port,$Subscription,$G.ViewDefinitionUrl Write-Verbose -Message "Acquiring ViewDef from URI: $GIResDEFUri" $ViewDef = Invoke-RestMethod -Uri $GIViewDefUri -Headers $Headers -Method Get Add-Member -InputObject $G -MemberType NoteProperty -Name ResDef -Value $ResDef Add-Member -InputObject $G -MemberType NoteProperty -Name ViewDef -Value $ViewDef $G.PublishDate = [datetime]$G.PublishDate $G.PSObject.TypeNames.Insert(0,$G.'odata.type') Write-Output -InputObject $G } } catch { throw $_ } finally { #Change Certificate Policy to the original if ($IgnoreSSL) { [System.Net.ServicePointManager]::CertificatePolicy = $OriginalCertificatePolicy } } } } function Get-WAPVMRoleOSDisk { <# .SYNOPSIS Retrieves Available VMRole OS Disks based on Gallery Item from Azure Pack TenantPublic or Tenant API. .PARAMETER Token Bearer Token acquired via Get-WAPToken. .PARAMETER UserId The UserId used to get the Bearer token. .PARAMETER PublicTenantAPIUrl The URL of either the TenantPublic API or Tenant API. .PARAMETER Port The Port where the TenantPublic (30006) or Tenant API (30005) is listening on. Defaults to 30006. .PARAMETER Subscription The subscription id to get the OS Disks from. .PARAMETER IgnoreSSL When using self-signed certificates, SSL validation will be ignored when this switch is enabled. .PARAMETER ViewDef The viewdef comes as a property of the VM Role gallery item. .EXAMPLE PS C:\>$URL = 'https://publictenantapi.mydomain.com' PS C:\>$creds = Get-Credential PS C:\>$token = Get-WAPToken -Credential $creds -URL 'https://sts.adfs.com' -ADFS PS C:\>$Subscription = Get-WAPSubscription -Token $token -UserId $creds.UserName -PublicTenantAPIUrl $URL -Port 443 -Name 'MySubscription' PS C:\>$GI = $Subscription | Get-WAPGalleryVMRole -Name MyVMRole PS C:\>$GI | Get-WAPVMRoleOSDisk -Verbose This will fetch all compatible and enabled OS disks. #> [CmdletBinding()] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [PSCustomObject] $ViewDef, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [String] $Token, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [String] $UserId, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [String] $PublicTenantAPIUrl, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [Alias('SubscriptionID')] [String] $Subscription, [Parameter(ValueFromPipelineByPropertyName)] [Int] $Port = 30006, [Switch] $IgnoreSSL ) process { try { if ($IgnoreSSL) { Write-Warning 'IgnoreSSL switch defined. Certificate errors will be ignored!' #Change Certificate Policy to ignore $OriginalCertificatePolicy = [System.Net.ServicePointManager]::CertificatePolicy IgnoreSSL } Write-Verbose 'Validating Token not expired' if (!(TestJWTClaimNotExpired -Token $Token)) { throw 'Token has expired, fetch a new one!' } Write-Verbose 'Constructing Header' $Headers = @{ Authorization = "Bearer $Token" 'x-ms-principal-id' = $UserId Accept = 'application/json' } $Headers | Out-String | Write-Debug $URI = '{0}:{1}/{2}/services/systemcenter/vmm/VirtualHardDisks' -f $PublicTenantAPIUrl,$Port,$Subscription Write-Verbose "Constructed VHD URI: $URI" $Sections = $ViewDef.ViewDefinition.Sections $Categories = $Sections | %{$_.Categories} $OSDiskParam = $Categories | %{$_.Parameters} | Where-Object{$_.Type -eq 'OSVirtualHardDisk'} $Images = Invoke-RestMethod -Uri $URI -Headers $Headers -Method Get foreach ($I in $Images.value) { $Tags = $I.tag if ((Compare-Object -ReferenceObject $Tags -DifferenceObject $OSDiskParam.ImageTags).SideIndicator -eq $null) { if ($I.enabled -eq $false) { continue } $I.AddedTime = [datetime] $I.AddedTime $I.ModifiedTime = [datetime] $I.ModifiedTime $I.ReleaseTime = [datetime] $I.ReleaseTime $I.PSObject.TypeNames.Insert(0,'WAP.GI.OSDisk') Write-Output -InputObject $I } } } catch { throw $_ } finally { #Change Certificate Policy to the original if ($IgnoreSSL) { [System.Net.ServicePointManager]::CertificatePolicy = $OriginalCertificatePolicy } } } } function Get-WAPVMNetwork { <# .SYNOPSIS Retrieves subscription available VM Networks from Azure Pack TenantPublic or Tenant API. .PARAMETER Token Bearer Token acquired via Get-WAPToken. .PARAMETER UserId The UserId used to get the Bearer token. .PARAMETER PublicTenantAPIUrl The URL of either the TenantPublic API or Tenant API. .PARAMETER Port The Port where the TenantPublic (30006) or Tenant API (30005) is listening on. Defaults to 30006. .PARAMETER Subscription The subscription id to get the VM Networks from. .PARAMETER List Defaults to list mode. Shows all VM Networks available to the subscription. .PARAMETER Name When Name is specified, only the VM Network with the specified name is returned. .PARAMETER IgnoreSSL When using self-signed certificates, SSL validation will be ignored when this switch is enabled. .EXAMPLE PS C:\>$URL = 'https://publictenantapi.mydomain.com' PS C:\>$creds = Get-Credential PS C:\>$token = Get-WAPToken -Credential $creds -URL 'https://sts.adfs.com' -ADFS PS C:\>$Subscription = Get-WAPSubscription -Token $token -UserId $creds.UserName -PublicTenantAPIUrl $URL -Port 443 -Name 'MySubscription' PS C:\>$Subscription | Get-WAPVMNetwork This will fetch all VM Networks available to the subscription. #> [CmdletBinding(DefaultParameterSetName='List')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [String] $Token, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [String] $UserId, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [String] $PublicTenantAPIUrl, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [Alias('SubscriptionId')] [String] $Subscription, [Parameter(ValueFromPipelineByPropertyName)] [Int] $Port = 30006, [Parameter(ParameterSetName='List')] [Switch] $List, [Parameter(Mandatory, ParameterSetName='Name')] [String] $Name, [Switch] $IgnoreSSL ) process { try { if ($IgnoreSSL) { Write-Warning 'IgnoreSSL switch defined. Certificate errors will be ignored!' #Change Certificate Policy to ignore $OriginalCertificatePolicy = [System.Net.ServicePointManager]::CertificatePolicy IgnoreSSL } Write-Verbose 'Validating Token not expired' if (!(TestJWTClaimNotExpired -Token $Token)) { throw 'Token has expired, fetch a new one!' } Write-Verbose 'Constructing Header' $Headers = @{ Authorization = "Bearer $Token" 'x-ms-principal-id' = $UserId Accept = 'application/json' } $Headers | Out-String | Write-Debug $URI = '{0}:{1}/{2}/services/systemcenter/vmm/VMNetworks' -f $PublicTenantAPIUrl,$Port,$Subscription Write-Verbose "Constructed VM Networks URI: $URI" $VMNets = Invoke-RestMethod -Uri $URI -Headers $Headers -Method Get foreach ($N in $VMNets.value) { if ($PSCmdlet.ParameterSetName -eq 'Name' -and $N.Name -ne $Name) { continue } $N.PSObject.TypeNames.Insert(0,'WAP.VMNetwork') Write-Output -InputObject $N } } catch { throw $_ } finally { #Change Certificate Policy to the original if ($IgnoreSSL) { [System.Net.ServicePointManager]::CertificatePolicy = $OriginalCertificatePolicy } } } } function New-WAPVMRoleParameterObject { <# .SYNOPSIS Generates VM Role Parameter Object. .PARAMETER VMRole VM Role gallery item object acquired via Get-WAPGalleryVMRole .PARAMETER OSDisk OS Disk object acquired via Get-WAPVMRoleOSDisk .PARAMETER VMRoleVMSize Select one of the default VMRole sizing profiles ('Small','A7','ExtraSmall','Large','A6','Medium','ExtraLarge') .PARAMETER VMNetwork VM Network object acquired via Get-WAPVMNetwork .PARAMETER Interactive Run in interactive mode where you get prompted to provide values with parameters. In non-interactive mode this functions uses the defaults where provided and uses NULL for everything unknown. .EXAMPLE PS C:\>$creds = Get-Credential PS C:\>$token = Get-WAPToken -Credential $creds -URL 'https://sts.domain.tld' -ADFS PS C:\>$Subscription = Get-WAPSubscription -Token $token -UserId $creds.UserName -PublicTenantAPIUrl https://api.domain.tld -Port 443 -Name 'MySub' PS C:\>$GI = $Subscription | Get-WAPGalleryVMRole -Name MyVMRole PS C:\>$OSDisk = $GI | Get-WAPVMRoleOSDisk | Sort-Object -Property AddedTime -Descending | Select-Object -First 1 PS C:\>$NW = $Subscription | Get-WAPVMNetwork -Name MyNetwork PS C:\>$VMProps = New-WAPVMRoleParameterObject -VMRole $GI -OSDisk $OSDisk -VMRoleVMSize Large -VMNetwork $NW -Interactive This will run in interactive mode. It will prompt to fill in the blanks and accept defaults or provide own values. .EXAMPLE PS C:\>$creds = Get-Credential PS C:\>$token = Get-WAPToken -Credential $creds -URL 'https://sts.domain.tld' -ADFS PS C:\>$Subscription = Get-WAPSubscription -Token $token -UserId $creds.UserName -PublicTenantAPIUrl https://api.domain.tld -Port 443 -Name 'MySub' PS C:\>$GI = $Subscription | Get-WAPGalleryVMRole -Name MyVMRole PS C:\>$OSDisk = $GI | Get-WAPVMRoleOSDisk | Sort-Object -Property AddedTime -Descending | Select-Object -First 1 PS C:\>$NW = $Subscription | Get-WAPVMNetwork -Name MyNetwork PS C:\>$VMProps = New-WAPVMRoleParameterObject -VMRole $GI -OSDisk $OSDisk -VMRoleVMSize Large -VMNetwork $NW PS C:\>$VMProps.MissingValue = 'MyValue' This will run in non-interactive mode. It will use defaults and assigns NULL if no default is available. Values can be assigned / overwritten. #> [CmdletBinding()] param ( [Parameter(Mandatory)] [Object] $VMRole, [Parameter(Mandatory)] [Object] $OSDisk, [Parameter(Mandatory)] [ValidateSet('Small','A7','ExtraSmall','Large','A6','Medium','ExtraLarge')] [String] $VMRoleVMSize, [Parameter(Mandatory)] [Object] $VMNetwork, [Switch] $Interactive ) if (!($VMRole.pstypenames.Contains('MicrosoftCompute.VMRoleGalleryItem'))) { throw 'Object bound to VMRole parameter is of the wrong type' } if (!($OSDisk.pstypenames.Contains('WAP.GI.OSDisk'))) { throw 'Object bound to OSDisk parameter is of the wrong type' } if (!($VMNetwork.pstypenames.Contains('WAP.VMNetwork'))) { throw 'Object bound to VMNetwork parameter is of the wrong type' } $Sections = $VMRole.ViewDef.ViewDefinition.Sections $Categories = $Sections | %{$_.Categories} $ViewDefParams = $Categories | %{$_.Parameters} $Output = [pscustomobject]@{} foreach ($P in $ViewDefParams) { $p | Out-String | Write-Verbose if ($Interactive -and $P.type -eq 'option') { $values = '' foreach ($v in $P.OptionValues) { $Def = ($v | Get-Member -MemberType NoteProperty).Definition.Split(' ')[1].Split('=') $Friendly = $Def[1] $Value = $Def[0] $values += $value + ',' } $values = $values.TrimEnd(',') if ($P.DefaultValue) { if(($result = Read-Host "Press enter to accept default value $($P.DefaultValue) for $($P.Name). Valid entries: $values") -eq ''){ Add-Member -InputObject $Output -MemberType NoteProperty -Name $P.Name -Value $P.DefaultValue -Force } else { do { $result = Read-Host "Enter one of the following entries: $values" } while (@($values.Split(',')) -notcontains $result) Add-Member -InputObject $Output -MemberType NoteProperty -Name $P.Name -Value $result -Force } } else { do { $result = Read-Host "Enter one of the following entries: $values" } while (@($values.Split(',')) -notcontains $result) Add-Member -InputObject $Output -MemberType NoteProperty -Name $P.Name -Value $result -Force } } elseif ($Interactive -and $P.type -eq 'Credential') { do { $result = Read-Host "Enter a credential for $($P.Name) in the format domain\username:password or username:password" } while ($result -notmatch '\w+\\+\w+:+\w+' -and $result -notmatch '\w+:+\w+') Add-Member -InputObject $Output -MemberType NoteProperty -Name $P.Name -Value $result -Force } elseif ($P.DefaultValue) { Add-Member -InputObject $Output -MemberType NoteProperty -Name $P.Name -Value $P.DefaultValue -Force } elseif ($P.Type -eq 'OSVirtualHardDisk') { Add-Member -InputObject $Output -MemberType NoteProperty -Name $P.Name -Value "$($OSDisk.FamilyName):$($OSDisk.Release)" -Force } elseif ($P.Type -eq 'VMSize') { Add-Member -InputObject $Output -MemberType NoteProperty -Name $P.Name -Value $VMRoleVMSize -Force } elseif ($P.Type -eq 'Credential') { Add-Member -InputObject $Output -MemberType NoteProperty -Name $P.Name -Value 'domain\username:password' -Force } elseif ($P.Type -eq 'Network') { Add-Member -InputObject $Output -MemberType NoteProperty -Name $P.Name -Value $($VMNetwork.Name) -Force } elseif ($Interactive) { $result = Read-Host "Enter a value for $($P.Name) of type $($P.Type)" Add-Member -InputObject $Output -MemberType NoteProperty -Name $P.Name -Value $result -Force } else { Add-Member -InputObject $Output -MemberType NoteProperty -Name $P.Name -Value $null -Force } } $Output.PSObject.TypeNames.Insert(0,'WAP.ParameterObject') Write-Output -InputObject $Output } function Get-WAPCloudService { <# .SYNOPSIS Retrieves Cloudservice deployed to subscription from Azure Pack TenantPublic or Tenant API. .PARAMETER Token Bearer Token acquired via Get-WAPToken. .PARAMETER UserId The UserId used to get the Bearer token. .PARAMETER PublicTenantAPIUrl The URL of either the TenantPublic API or Tenant API. .PARAMETER Port The Port where the TenantPublic (30006) or Tenant API (30005) is listening on. Defaults to 30006. .PARAMETER Subscription The subscription id to get the cloud service from. .PARAMETER List Defaults to list mode. Shows all cloud services provisioned for the subscription. .PARAMETER Name When Name is specified, only the cloud service with the specified name is returned. .PARAMETER IgnoreSSL When using self-signed certificates, SSL validation will be ignored when this switch is enabled. .EXAMPLE PS C:\>$URL = 'https://publictenantapi.mydomain.com' PS C:\>$creds = Get-Credential PS C:\>$token = Get-WAPAdfsToken -Credential $creds -URL 'https://sts.adfs.com' PS C:\>$Subscription = Get-WAPSubscription -Token $token -UserId $creds.UserName -PublicTenantAPIUrl $URL -Port 443 -Name 'MySubscription' PS C:\>$Subscription | Get-WAPCloudService This will retreive all provisioned cloud services for the specified subscription. #> [CmdletBinding(DefaultParameterSetName = 'List')] param ( [Parameter(ParameterSetName = 'List')] [Switch] $List, [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'Name')] [Alias('CloudServiceName')] [String] $Name, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [String] $Token, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [String] $UserId, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [String] $PublicTenantAPIUrl, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [Alias('SubscriptionId')] [String] $Subscription, [Parameter(ValueFromPipelineByPropertyName)] [Int] $Port = 30006, [Switch] $IgnoreSSL ) process { try { if ($IgnoreSSL) { Write-Warning 'IgnoreSSL switch defined. Certificate errors will be ignored!' #Change Certificate Policy to ignore $OriginalCertificatePolicy = [System.Net.ServicePointManager]::CertificatePolicy IgnoreSSL } Write-Verbose 'Validating Token not expired' if (!(TestJWTClaimNotExpired -Token $Token)) { throw 'Token has expired, fetch a new one!' } Write-Verbose 'Constructing Header' $Headers = @{ Authorization = "Bearer $Token" 'x-ms-principal-id' = $UserId Accept = 'application/json' } $Headers | Out-String | Write-Debug $URI = '{0}:{1}/{2}/CloudServices?api-version=2013-03' -f $PublicTenantAPIUrl,$Port,$Subscription Write-Verbose "Constructed CloudService URI: $URI" $CloudServices = Invoke-RestMethod -Uri $URI -Headers $Headers -Method Get [void] $PSBoundParameters.Remove('Name') [void] $PSBoundParameters.Remove('List') foreach ($C in $CloudServices.value) { if ($PSCmdlet.ParameterSetName -eq 'Name' -and $C.Name -ne $Name) { continue } $PSBoundParameters.GetEnumerator() | %{ Add-Member -InputObject $C -MemberType NoteProperty -Name $_.Key -Value $_.Value } Add-Member -InputObject $C -MemberType AliasProperty -Name CloudServiceName -Value Name $C.PSObject.TypeNames.Insert(0,'WAP.CloudService') Write-Output -InputObject $C } } catch { throw $_ } finally { #Change Certificate Policy to the original if ($IgnoreSSL) { [System.Net.ServicePointManager]::CertificatePolicy = $OriginalCertificatePolicy } } } } function New-WAPCloudService { <# .SYNOPSIS Creates Cloudservice for subscription from Azure Pack TenantPublic or Tenant API. .PARAMETER Token Bearer Token acquired via Get-WAPToken. .PARAMETER UserId The UserId used to get the Bearer token. .PARAMETER PublicTenantAPIUrl The URL of either the TenantPublic API or Tenant API. .PARAMETER Port The Port where the TenantPublic (30006) or Tenant API (30005) is listening on. Defaults to 30006. .PARAMETER Subscription The subscription id to provision the cloud service to. .PARAMETER Name The name of the cloud service to be provisioned. The name must be unique within the subscription. .PARAMETER IgnoreSSL When using self-signed certificates, SSL validation will be ignored when this switch is enabled. .EXAMPLE PS C:\>$URL = 'https://publictenantapi.mydomain.com' PS C:\>$creds = Get-Credential PS C:\>$token = Get-WAPToken -Credential $creds -URL 'https://sts.adfs.com' -ADFS PS C:\>$Subscription = Get-WAPSubscription -Token $token -UserId $creds.UserName -PublicTenantAPIUrl $URL -Port 443 -Name 'MySubscription' PS C:\>$Subscription | New-WAPCloudService -Name test This will provision a cloud service named test. #> [CmdletBinding()] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [String] $Token, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [String] $UserId, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [String] $PublicTenantAPIUrl, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [Alias('SubscriptionId')] [String] $Subscription, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [Alias('CloudServiceName')] [String] $Name, [Parameter(ValueFromPipelineByPropertyName)] [Int] $Port = 30006, [Switch] $IgnoreSSL ) process { try { if ($IgnoreSSL) { Write-Warning 'IgnoreSSL switch defined. Certificate errors will be ignored!' #Change Certificate Policy to ignore $OriginalCertificatePolicy = [System.Net.ServicePointManager]::CertificatePolicy IgnoreSSL } Write-Verbose 'Validating Token not expired' if (!(TestJWTClaimNotExpired -Token $Token)) { throw 'Token has expired, fetch a new one!' } Write-Verbose 'Constructing Header' $Headers = @{ Authorization = "Bearer $Token" 'x-ms-principal-id' = $UserId Accept = 'application/json' } $Headers | Out-String | Write-Debug $URI = '{0}:{1}/{2}/CloudServices?api-version=2013-03' -f $PublicTenantAPIUrl,$Port,$Subscription Write-Verbose "Constructed CloudService URI: $URI" $CloudServiceConfig = @{ Name = $Name Label = $Name } | ConvertTo-Json -Compress $CloudService = Invoke-RestMethod -Uri $URI -Headers $Headers -Method Post -Body $CloudServiceConfig -ContentType 'application/json' [void] $PSBoundParameters.Remove('Name') $PSBoundParameters.GetEnumerator() | %{ Add-Member -InputObject $CloudService -MemberType NoteProperty -Name $_.Key -Value $_.Value } $CloudService.PSObject.Properties.Remove('odata.metadata') $CloudService.PSObject.TypeNames.Insert(0,'WAP.CloudService') Write-Output -InputObject $CloudService } catch { throw $_ } finally { #Change Certificate Policy to the original if ($IgnoreSSL) { [System.Net.ServicePointManager]::CertificatePolicy = $OriginalCertificatePolicy } } } } function Remove-WAPCloudService { <# .SYNOPSIS Deletes Cloudservice from subscription from Azure Pack TenantPublic or Tenant API. .PARAMETER Token Bearer Token acquired via Get-WAPToken. .PARAMETER UserId The UserId used to get the Bearer token. .PARAMETER PublicTenantAPIUrl The URL of either the TenantPublic API or Tenant API. .PARAMETER Port The Port where the TenantPublic (30006) or Tenant API (30005) is listening on. Defaults to 30006. .PARAMETER Subscription The subscription id to get remove the cloud service from. .PARAMETER Name The name of the cloud service to be removed. .PARAMETER Force If Force is not specified, removal is treated with confirm impact high. .PARAMETER IgnoreSSL When using self-signed certificates, SSL validation will be ignored when this switch is enabled. .EXAMPLE PS C:\>$URL = 'https://publictenantapi.mydomain.com' PS C:\>$creds = Get-Credential PS C:\>$token = Get-WAPToken -Credential $creds -URL 'https://sts.adfs.com' -ADFS PS C:\>$Subscription = Get-WAPSubscription -Token $token -UserId $creds.UserName -PublicTenantAPIUrl $URL -Port 443 -Name 'MySubscription' PS C:\>$Subscription | Remove-WAPCloudService -Name test This will remove the cloudservice named test from the subscription. If a VM Role has been deployed to this cloud service, it will be removed as well. In this case, the user will be prompted to confirm the remove action as -Force or -Confirm:$false is not specified. .EXAMPLE PS C:\>$URL = 'https://publictenantapi.mydomain.com' PS C:\>$creds = Get-Credential PS C:\>$token = Get-WAPToken -Credential $creds -URL 'https://sts.adfs.com' -ADFS PS C:\>$Subscription = Get-WAPSubscription -Token $token -UserId $creds.UserName -PublicTenantAPIUrl $URL -Port 443 -Name 'MySubscription' PS C:\>$Subscription | Get-WAPCloudService -Name Test | Remove-WAPCloudService -Force This will remove the cloudservice named test from the subscription. If a VM Role has been deployed to this cloud service, it will be removed as well. In this case, the user is not prompted to confirm as -Force is specified. #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact='High')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [String] $Name, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [String] $Token, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [String] $UserId, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [String] $PublicTenantAPIUrl, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [Alias('SubscriptionId')] [String] $Subscription, [Parameter(ValueFromPipelineByPropertyName)] [Int] $Port = 30006, [Switch] $Force, [Switch] $IgnoreSSL ) process { try { if ($IgnoreSSL) { Write-Warning 'IgnoreSSL switch defined. Certificate errors will be ignored!' #Change Certificate Policy to ignore $OriginalCertificatePolicy = [System.Net.ServicePointManager]::CertificatePolicy IgnoreSSL } Write-Verbose 'Validating Token not expired' if (!(TestJWTClaimNotExpired -Token $Token)) { throw 'Token has expired, fetch a new one!' } Write-Verbose 'Constructing Header' $Headers = @{ Authorization = "Bearer $Token" 'x-ms-principal-id' = $UserId Accept = 'application/json' } $Headers | Out-String | Write-Debug $URI = '{0}:{1}/{2}/CloudServices?api-version=2013-03' -f $PublicTenantAPIUrl,$Port,$Subscription Write-Verbose "Constructed CloudService URI: $URI" $CloudServices = Invoke-RestMethod -Uri $URI -Method Get -Headers $Headers foreach ($C in $CloudServices.value) { if ($C.Name -ne $Name) { continue } $RemURI = '{0}:{1}/{2}/CloudServices/{3}?api-version=2013-03' -f $PublicTenantAPIUrl,$Port,$Subscription,$Name Write-Verbose "Constructed Named CloudService URI: $RemURI" if ($Force -or $PSCmdlet.ShouldProcess($Name)) { Invoke-RestMethod -Uri $RemURI -Method Delete -Headers $Headers | Out-Null } } } catch { throw $_ } finally { #Change Certificate Policy to the original if ($IgnoreSSL) { [System.Net.ServicePointManager]::CertificatePolicy = $OriginalCertificatePolicy } } } } function New-WAPVMRoleDeployment { <# .SYNOPSIS Deploys VM Role to a Cloudservice using Azure Pack TenantPublic or Tenant API. .PARAMETER Token Bearer Token acquired via Get-WAPToken. .PARAMETER UserId The UserId used to get the Bearer token. .PARAMETER PublicTenantAPIUrl The URL of either the TenantPublic API or Tenant API. .PARAMETER Port The Port where the TenantPublic (30006) or Tenant API (30005) is listening on. Defaults to 30006. .PARAMETER Subscription The subscription id to get the VM Role Gallery Item from. .PARAMETER CloudServiceName The name of the cloud service to provision to. If it does not exist, it will be created. .PARAMETER VMRole Object acquired with Get-WAPGalleryVMRole. .PARAMETER ParameterObject Object acquired with New-WAPVMRoleParameterObject. .PARAMETER IgnoreSSL When using self-signed certificates, SSL validation will be ignored when this switch is enabled. .EXAMPLE PS C:\>$URL = 'https://publictenantapi.mydomain.com' PS C:\>$creds = Get-Credential PS C:\>$token = Get-WAPToken -Credential $creds -URL 'https://sts.adfs.com' -ADFS PS C:\>$Subscription = Get-WAPSubscription -Token $token -UserId $creds.UserName -PublicTenantAPIUrl $URL -Port 443 -Name 'MySubscription' PS C:\>$GI = $Subscription | Get-WAPGalleryVMRole -Name DomainController PS C:\>$OSDisk = $GI | Get-WAPVMRoleOSDisk | Sort-Object -Property AddedTime -Descending | Select-Object -First 1 PS C:\>$NW = $Subscription | Get-WAPVMNetwork -Name Private PS C:\>$VMProps = New-WAPVMRoleParameterObject -VMRole $GI -OSDisk $OSDisk -VMRoleVMSize Large -VMNetwork $NW PS C:\>$VMProps.DomainName = 'MyNewDomain.local' PS C:\>$Subscription | New-WAPVMRoleDeployment -VMRole $GI -ParameterObject $VMProps -CloudServiceName DCs -Verbose This will deploy a new VM Role based on the Gallery Item DomainController. It will link the VMs up to the Private network and uses the latest published OS Disk. The domain name for the VM Role will be 'MyNewDomain.local' and the VMs will be sided using the Large VM Profile. If the cloud service DCs does not yet exists, it will be created. If it does exist, it will be checked if it has the correct name and if no VM Roles have been deployed to it. This function mirrors portal functionality and therefore does not allow multiple VM Roles in one cloud service. #> [CmdletBinding()] param ( [Parameter(Mandatory)] [Object] $VMRole, [Parameter(Mandatory)] [Object] $ParameterObject, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [String] $Token, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [String] $UserId, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [String] $PublicTenantAPIUrl, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [Alias('SubscriptionId')] [String] $Subscription, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [Int] $Port = 30006, [Switch] $IgnoreSSL, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [Alias('Name','VMRoleName')] [String] $CloudServiceName ) process { if (!($VMRole.pstypenames.Contains('MicrosoftCompute.VMRoleGalleryItem'))) { throw 'Object bound to VMRole parameter is of the wrong type' } if (!($ParameterObject.pstypenames.Contains('WAP.ParameterObject'))) { throw 'Object bound to ParameterObject parameter is of the wrong type' } $ParameterObject | gm -MemberType Properties | %{ if ($ParameterObject.($_.name) -eq $null) { throw "ParameterObject property: $($_.name) is NULL" } } $ErrorActionPreference = 'Stop' $SUB = New-Object -TypeName psobject -Property $PSBoundParameters $SUB.PSObject.TypeNames.Insert(0,'WAP.Subscription') try { if ($IgnoreSSL) { Write-Warning 'IgnoreSSL switch defined. Certificate errors will be ignored!' #Change Certificate Policy to ignore $OriginalCertificatePolicy = [System.Net.ServicePointManager]::CertificatePolicy IgnoreSSL } Write-Verbose 'Validating Token not expired' if (!(TestJWTClaimNotExpired -Token $Token)) { throw 'Token has expired, fetch a new one!' } Write-Verbose -Message "Testing if Cloudservice $CloudServiceName exists" if (!($SUB | Get-WAPCloudService)) { Write-Verbose -Message "Creating Cloudservice $CloudServiceName as it does not yet exist" $SUB | New-WAPCloudService | Out-Null $New = $true } else { $New = $false } if (!$New) { Write-Verbose -Message "Testing if VMRole with name $VMRoleName does not already exist" if ($SUB | Get-WAPCloudService | Get-WAPVMRole) { throw "There is already a VMRole deployed to the CloudService $CloudServiceName. Because this function mimics portal experience, only one VM Role is allowed to exist per CloudService" } } #Add ResDefConfig JSON to Dictionary $ResDefConfig = New-Object 'System.Collections.Generic.Dictionary[String,Object]' $ResDefConfig.Add('Version',$VMRole.version) $ResDefConfig.Add('ParameterValues',($ParameterObject | ConvertTo-Json)) # Set Gallery Item Payload Info $GIPayload = @{ InstanceView = $null Substate = $null Name = $CloudServiceName Label = $CloudServiceName ProvisioningState = $null ResourceConfiguration = $ResDefConfig ResourceDefinition = $VMRole.ResDef } # Convert Gallery Item Payload Info To JSON $GIPayloadJSON = ConvertTo-Json $GIPayload -Depth 10 # Deploy VM Role to cloudservice Write-Verbose 'Constructing Header' $Headers = @{ Authorization = "Bearer $Token" 'x-ms-principal-id' = $UserId Accept = 'application/json' } $Headers | Out-String | Write-Debug $URI = '{0}:{1}/{2}/CloudServices/{3}/Resources/MicrosoftCompute/VMRoles/?api-version=2013-03' -f $PublicTenantAPIUrl,$Port,$Subscription,$CloudServiceName Write-Verbose "Constructed VMRole Deploy URI: $URI" Write-Verbose "Starting deployment of VMRole $VMRoleName to CloudService $CloudServiceName" $Deploy = Invoke-RestMethod -Uri $URI -Headers $Headers -Method Post -Body $GIPayloadJSON -ContentType 'application/json' $Deploy.PSObject.TypeNames.Insert(0,'WAP.VMRole') Write-Output $Deploy } catch { if ($New) { $SUB | Remove-WAPCloudService -Force } throw $_ } finally { #Change Certificate Policy to the original if ($IgnoreSSL) { [System.Net.ServicePointManager]::CertificatePolicy = $OriginalCertificatePolicy } } } } function Get-WAPVMRole { <# .SYNOPSIS Retrieves Deployed VM Role information from Azure Pack TenantPublic or Tenant API. .PARAMETER Token Bearer Token acquired via Get-WAPToken. .PARAMETER UserId The UserId used to get the Bearer token. .PARAMETER PublicTenantAPIUrl The URL of either the TenantPublic API or Tenant API. .PARAMETER Port The Port where the TenantPublic (30006) or Tenant API (30005) is listening on. Defaults to 30006. .PARAMETER Subscription The subscription id to get the VM Role information from. .PARAMETER CloudServiceName The name of the cloud service to get VM Role information from. .PARAMETER IgnoreSSL When using self-signed certificates, SSL validation will be ignored when this switch is enabled. .EXAMPLE PS C:\>$URL = 'https://publictenantapi.mydomain.com' PS C:\>$creds = Get-Credential PS C:\>$token = Get-WAPToken -Credential $creds -URL 'https://sts.adfs.com' -ADFS PS C:\>$Subscription = Get-WAPSubscription -Token $token -UserId $creds.UserName -PublicTenantAPIUrl $URL -Port 443 -Name 'MySubscription' PS C:\>$Subscription | Get-WAPCloudService -Name DCs | Get-WAPVMRole | select * This will get the VM Role provisioning information for the DCs cloud service deployment. #> [CmdletBinding()] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [Alias('Name','VMRoleName')] [String] $CloudServiceName, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [String] $Token, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [String] $UserId, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [String] $PublicTenantAPIUrl, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [String] $Subscription, [Parameter(ValueFromPipelineByPropertyName)] [Int] $Port = 30006, [Switch] $IgnoreSSL ) process { try { if ($IgnoreSSL) { Write-Warning 'IgnoreSSL switch defined. Certificate errors will be ignored!' #Change Certificate Policy to ignore $OriginalCertificatePolicy = [System.Net.ServicePointManager]::CertificatePolicy IgnoreSSL } Write-Verbose 'Validating Token not expired' if (!(TestJWTClaimNotExpired -Token $Token)) { throw 'Token has expired, fetch a new one!' } Write-Verbose 'Constructing Header' $Headers = @{ Authorization = "Bearer $Token" 'x-ms-principal-id' = $UserId Accept = 'application/json' } $Headers | Out-String | Write-Debug $URI = '{0}:{1}/{2}/CloudServices/{3}/Resources/MicrosoftCompute/VMRoles?api-version=2013-03' -f $PublicTenantAPIUrl,$Port,$Subscription,$CloudServiceName Write-Verbose "Constructed VMRole URI: $URI" $Roles = Invoke-RestMethod -Uri $URI -Headers $Headers -Method Get foreach ($R in $Roles.value) { Add-Member -InputObject $R -MemberType NoteProperty -Name ParameterValues -Value ($R.ResourceConfiguration.ParameterValues | ConvertFrom-Json) Add-Member -InputObject $R -MemberType NoteProperty -Name ScaleOutSettings -Value $R.ResourceDefinition.IntrinsicSettings.ScaleOutSettings Add-Member -InputObject $R -MemberType NoteProperty -Name InstanceCount -Value $R.InstanceView.InstanceCount Add-Member -InputObject $R -MemberType NoteProperty -Name VMSize -Value $R.InstanceView.ResolvedResourceDefinition.IntrinsicSettings.HardwareProfile.VMSize $R.PSObject.TypeNames.Insert(0,'WAP.VMRole') Write-Output -InputObject $R } } catch { throw $_ } finally { #Change Certificate Policy to the original if ($IgnoreSSL) { [System.Net.ServicePointManager]::CertificatePolicy = $OriginalCertificatePolicy } } } } Export-ModuleMember *-WAP* |