UcsRest.psm1
Function Set-UcsRestParameter { <# .SYNOPSIS Set a parameter for this specific phone. .DESCRIPTION Uses the "Set" API endpoint to set the value of a parameter. .PARAMETER IPv4Address The IP address of the target phone, in the format 192.168.1.234. .PARAMETER Parameter The name of the parameter to set. .PARAMETER Value The value to set. $True is converted to 1 and $False is converted to 0. .PARAMETER Quiet Suppresses warnings and some errors, and inhibits result output. .NOTES Phone may reboot after setting a parameter, especially in the case of an invalid assignment. #> [CmdletBinding(SupportsShouldProcess,ConfirmImpact = 'High')] Param([Parameter(Mandatory,HelpMessage = '127.0.0.1',ValueFromPipelineByPropertyName,ValueFromPipeline)][ValidatePattern('^([0-2]?[0-9]{1,2}\.){3}([0-2]?[0-9]{1,2})$')][String[]]$IPv4Address, [Parameter(Mandatory,HelpMessage = 'A valid UCS parameter, such as Up.Timeout',ValueFromPipelineByPropertyName)][String]$Parameter, [Parameter(Mandatory,HelpMessage = 'A valid value for the specified parameter.')][AllowEmptyString()][String]$Value, [Switch]$PassThru) BEGIN { if($Value -eq $true) { $Value = '1' } elseif($Value -eq $false) { $Value = '0' } Try { $ThisParameter = Get-UcsCleanJSON -String $Parameter -ErrorAction Stop } Catch { $Exception = New-Object $_.Exception.GetType().BaseType ("Couldn't process provided parameter $Parameter on $ThisIPv4Address.",$_) #Grab the exception object type from the inner exception and attach the inner exception. Throw $Exception } Try { $ThisValue = Get-UcsCleanJSON -String $Value -ErrorAction Stop } Catch { Write-Debug "Got an error when trying to clean value. Empty string?" $ThisValue = "" } $ParameterSet = ("{{`"data`":{{`"{0}`": `"{1}`"}}}}" -f $ThisParameter, $ThisValue) } PROCESS { FOREACH($ThisIPv4Address in $IPv4Address) { if($PSCmdlet.ShouldProcess(('{0}' -f $ThisIPv4Address))) { Try { $ThisOutput = Invoke-UcsRestMethod -IPv4Address $ThisIPv4Address -ApiEndpoint 'api/v1/mgmt/config/set' -Method 'Post' -Body $ParameterSet -ErrorAction Stop } Catch { $Exception = New-Object $_.Exception.GetType().BaseType ("Couldn't set parameter $Parameter with value $Value on $ThisIPv4Address.",$_) #Grab the exception object type from the inner exception and attach the inner exception. Throw $Exception } if($ThisOutput.Status.IsSuccess -eq $false) { Write-Error "Couldn't set parameter $Parameter with value $Value on $ThisIPv4Address. Phone returned an error." Continue } } } } END { } } Function Get-UcsRestParameter { <# .SYNOPSIS Retrieve configuration parameter .DESCRIPTION Add a more complete description of what the function does. .PARAMETER IPv4Address The network address in IPv4 notation, such as 192.123.45.67. .PARAMETER Parameter One or more parameter names. #> Param([Parameter(Mandatory,HelpMessage = '127.0.0.1',ValueFromPipelineByPropertyName,ValueFromPipeline)][ValidatePattern('^([0-2]?[0-9]{1,2}\.){3}([0-2]?[0-9]{1,2})$')][String[]]$IPv4Address, [Parameter(Mandatory,HelpMessage = 'A UCS parameter, such as "Up.Timeout."',ValueFromPipelineByPropertyName)][String[]]$Parameter, [Switch]$Quiet, [Int][ValidateRange(1,100)]$Retries = (Get-UcsConfig -Api REST).Retries) BEGIN { $OutputArray = New-Object -TypeName System.Collections.ArrayList $MaxParameters = 20 #TODO: The REST API only lets us request 20 parameters at a time, but we could invisibly batch them for the user. if($Parameter.count -gt $MaxParameters) { Write-Error ('{0} parameters were provided, maximum is {1}.' -f $Parameter.count, $MaxParameters) -ErrorAction Stop -RecommendedAction 'Reduce the number of parameters and try again.' } } PROCESS { foreach($ThisIPv4Address in $IPv4Address) { $ParameterString = '' Foreach($ThisParameter in $Parameter) { $ThisParameter = Get-UcsCleanJSON -String $ThisParameter $ParameterString += ('"{0}",' -f $ThisParameter) } $ParameterString = $ParameterString.Substring(0,($ParameterString.Length - 1)) $ParameterName = ("{{`"data`":[{0}]}}" -f $ParameterString) Try { $RawOutput = Invoke-UcsRestMethod -IPv4Address $ThisIPv4Address -ApiEndpoint 'api/v1/mgmt/config/get' -Body $ParameterName -Method Post -Retries $Retries $Output = $RawOutput.Data $InvalidParams = $RawOutput.InvalidParams } Catch { Write-Error -Message "Could not get parameter $Parameter for $ThisIPv4Address." Continue #No need to process more. } Try { $ParameterNames = $Output | Get-Member -ErrorAction Stop | Where-Object -Property MemberType -EQ -Value 'NoteProperty' | Select-Object -ExpandProperty Name } Catch { Write-Error -Message "Could not parse parameter information for $ThisIPv4Address." } Try { $InvalidParameterNames = $InvalidParams | Get-Member -ErrorAction Stop | Where-Object -Property MemberType -EQ -Value 'NoteProperty' | Select-Object -ExpandProperty Name } Catch { Write-Debug -Message "No invalid parameters detected for $ThisIPv4Address." } Foreach($ParameterName in $ParameterNames) { $ThisResult = New-Object -TypeName PsCustomObject $ThisResult | Add-Member -MemberType NoteProperty -Name IPv4Address -Value $ThisIPv4Address $ThisResult | Add-Member -MemberType NoteProperty -Name Parameter -Value $ParameterName Try { $ThisParameterResult = $Output | Select-Object -ExpandProperty $ParameterName -ErrorAction Stop $ThisResult | Add-Member -MemberType NoteProperty -Name Value -Value $ThisParameterResult.Value $ThisResult | Add-Member -MemberType NoteProperty -Name Source -Value $ThisParameterResult.Source } Catch { Write-Error -Message "Couldn't create a parameter output object for $ThisIPv4Address" $ThisResult | Add-Member -MemberType NoteProperty -Name Value -Value $null $ThisResult | Add-Member -MemberType NoteProperty -Name Source -Value "Error" } $null = $OutputArray.Add($ThisResult) } Foreach($IdName in $InvalidParameterNames) { $ParameterName = $InvalidParams.$IdName Write-Warning "$ParameterName is not a valid parameter name for $ThisIPv4Address." $ThisResult = New-Object -TypeName PsCustomObject $ThisResult | Add-Member -MemberType NoteProperty -Name IPv4Address -Value $ThisIPv4Address $ThisResult | Add-Member -MemberType NoteProperty -Name Parameter -Value $ParameterName $ThisResult | Add-Member -MemberType NoteProperty -Name Value -Value $null $ThisResult | Add-Member -MemberType NoteProperty -Name Source -Value "InvalidParams" $null = $OutputArray.Add($ThisResult) } } } END { Return $OutputArray } } Function Get-UcsRestNetworkInfo { <# .SYNOPSIS Returns basic networking information. .PARAMETER IPv4Address The network address in IPv4 notation, such as 192.123.45.67. #> Param([Parameter(Mandatory,HelpMessage = '127.0.0.1',ValueFromPipelineByPropertyName,ValueFromPipeline)][ValidatePattern('^([0-2]?[0-9]{1,2}\.){3}([0-2]?[0-9]{1,2})$')][String[]]$IPv4Address, [Switch]$Quiet, [Int][ValidateRange(1,100)]$Retries = (Get-UcsConfig -Api REST).Retries) BEGIN { $OutputArray = New-Object -TypeName System.Collections.ArrayList } PROCESS { foreach($ThisIPv4Address in $IPv4Address) { $Output = Invoke-UcsRestMethod -IPv4Address $ThisIPv4Address -ApiEndpoint 'api/v1/mgmt/network/info' -Retries $Retries $Modified = $Output.data #Process the provisioning server for consistency with other cmdlets. $ProvisioningServer = $Modified.ProvServerAddress.Trim() $ProvisioningServer = $ProvisioningServer.Replace('/','\') #Make all slashes the same. $ProvisioningServerIndex = $ProvisioningServer.LastIndexOf('\') + 1 if($ProvisioningServerIndex -gt 0) { $ProvisioningServer = $ProvisioningServer.Substring($ProvisioningServerIndex) } $Modified.ProvServerAddress = $ProvisioningServer if($Modified.DHCP -eq "enabled") { $DHCPEnabled = $true } elseif($Modified.DHCP -eq "disabled") { $DHCPEnabled = $false } else { $DHCPEnabled = $null } $Modified = $Modified | Select-Object -ExcludeProperty DHCP -Property *,@{Name="DHCPEnabled";Expression={$DHCPEnabled}} $null = $OutputArray.Add($Modified) } } END { Return $OutputArray } } Function Get-UcsRestDeviceInfo { <# .SYNOPSIS Returns basic device information. .DESCRIPTION Returns model information, firmware version information, uptime, MAC address, and information on attached devices. .PARAMETER IPv4Address The network address in IPv4 notation, such as 192.123.45.67. .PARAMETER Quiet Prevents the API call from returning warnings when problems occur. .EXAMPLE Get-DeviceInfo -IPv4Address 192.168.1.20 -Quiet Returns device info without returning any warnings in case of a problem. .NOTES AttachedHardware is a hashtable with multiple objects inside it representing the attached devices. #> Param([Parameter(Mandatory,HelpMessage = '127.0.0.1',ValueFromPipelineByPropertyName,ValueFromPipeline)][ValidatePattern('^([0-2]?[0-9]{1,2}\.){3}([0-2]?[0-9]{1,2})$')][String[]]$IPv4Address, [Switch]$Quiet, [Int][ValidateRange(1,100)]$Retries = (Get-UcsConfig -Api REST).Retries) BEGIN { } PROCESS { foreach($ThisIPv4Address in $IPv4Address) { Try { Write-Debug -Message "Connecting to $ThisIPv4Address" $Output = Invoke-UcsRestMethod -IPv4Address $ThisIPv4Address -ApiEndpoint 'api/v1/mgmt/device/info' -Method Get -Retries $Retries -ErrorAction Stop $OutputData = $Output.Data } Catch { Write-Error -Message "Couldn't connect to $ThisIPv4Address" } if($null -ne $OutputData) { $OutputObject = New-Object PsCustomObject Write-Debug -Message "Parsing data for $ThisIPv4Address" $OutputObject | Add-Member -MemberType NoteProperty -Name IPv4Address -Value $ThisIPv4Address $MacAddress = $OutputData.MacAddress $OutputObject | Add-Member -MemberType NoteProperty -Name MacAddress -Value $MacAddress $ModelNumber = $OutputData.ModelNumber if($ModelNumber -eq "Trio 8800") { #Some versions of the Trio firmware output the model differently. #TODO: If we find this is true on a lot of models/firmwares, implement some sort of table for this data. $ModelNumber = "RealPresence Trio 8800" } $OutputObject | Add-Member -MemberType NoteProperty -Name Model -Value $ModelNumber $DeviceVendor = $OutputData.DeviceVendor $OutputObject | Add-Member -MemberType NoteProperty -Name DeviceVendor -Value $DeviceVendor $DeviceType = $OutputData.DeviceType $OutputObject | Add-Member -MemberType NoteProperty -Name DeviceType -Value $DeviceType $AttachedHardware = $OutputData.AttachedHardware $OutputObject | Add-Member -MemberType NoteProperty -Name AttachedHardware -Value $AttachedHardware <### Get firmware info ###> if( ($OutputData | Get-Member).Name -contains 'Firmware') { #If we're running on a 5.7.X firmware, there's no FirmwareRelease row, so we need to add it from the new Firmware row. $Updater = $OutputData.Firmware.Updater $OutputObject | Add-Member -MemberType NoteProperty -Name UpdaterFirmware -Value $Updater $ApplicationFirmware = $OutputData.Firmware.Application $null = $ApplicationFirmware -match '(\d+\.){3}\d{4,}[A-Z]?' $ApplicationFirmware = $Matches[0] $OutputObject | Add-Member -MemberType NoteProperty -Name FirmwareRelease -Value $ApplicationFirmware $BootBlock = $OutputData.Firmware.BootBlock $null = $BootBlock -match '(\d+\.){3}\d{4,}[A-Z]?' $BootBlock = $Matches[0] $OutputObject | Add-Member -MemberType NoteProperty -Name BootBlockFirmware -Value $BootBlock } elseif( ($OutputData | Get-Member).Name -contains 'FirmwareRelease') { #On non-5.7.X firmwares, just grab the FirmwareRelease property. $OutputObject | Add-Member -MemberType NoteProperty -Name FirmwareRelease -Value $OutputData.FirmwareRelease } else { Write-Warning "Couldn't get firmware release for $ThisIPv4Address. Possible API change?" } <#### Get the uptime ###> if( ($OutputData | Get-Member).Name -contains "UpTime") { #Version 5.7.0 $Uptime = New-Timespan -Days $OutputData.Uptime.Days -Hours $OutputData.Uptime.Hours -Minutes $OutputData.Uptime.Minutes -Seconds $OutputData.Uptime.Seconds } else { #All other versions $Uptime = Convert-UcsUptimeString -Uptime ($OutputData.UpTimeSinceLastReboot) } $OutputObject | Add-Member -MemberType NoteProperty -Name UpTimeSinceLastReboot -Value $Uptime $LastReboot = (Get-Date) - ($Uptime) $OutputObject | Add-Member -MemberType NoteProperty -Name LastReboot -Value $LastReboot $OutputObject } } } END { } } Function Restart-UcsRestPhone { <# .SYNOPSIS Restarts a phone. .DESCRIPTION Invokes the safeRestart API endpoint to restart the phone. The phone will not restart in the middle of a call, but will restart as soon as possible thereafter. .PARAMETER IPv4Address The network address in IPv4 notation, such as 192.123.45.67. .NOTES Will generate warnings for each phone which does not successfully restart, and status objects for each phone successfully restarted. If -Quiet is specified, no output will be returned. #> [CmdletBinding(SupportsShouldProcess,ConfirmImpact = 'High')] Param([Parameter(Mandatory,HelpMessage = '127.0.0.1',ValueFromPipelineByPropertyName,ValueFromPipeline)][ValidatePattern('^([0-2]?[0-9]{1,2}\.){3}([0-2]?[0-9]{1,2})$')][String[]]$IPv4Address, [Switch]$PassThru, [String][ValidateSet('Reboot','Restart')]$Type = 'Reboot', [Int][ValidateRange(1,100)]$Retries = (Get-UcsConfig -Api REST).Retries) BEGIN { } PROCESS { foreach($ThisIPv4Address in $IPv4Address) { if($PSCmdlet.ShouldProcess(('{0}' -f $ThisIPv4Address))) { if($Type -eq 'Reboot') { $ApiEndpoint = 'api/v1/mgmt/safeReboot' } else { $ApiEndpoint = 'api/v1/mgmt/safeRestart' } Write-Verbose -Message ('Sending {1} command to {0}.' -f $ThisIPv4Address,$Type) Try { $ThisResult = Invoke-UcsRestMethod -IPv4Address $ThisIPv4Address -ApiEndpoint $ApiEndpoint -Method Post -Retries $Retries -ErrorAction Stop } Catch { Write-Debug -Message $_ Write-Error -Message "Could not $Type phone $ThisIPv4Address. Could not connect to phone." } if($ThisResult.Status.IsSuccess -ne $true) { Write-Error -Message "Failed to $Type phone $ThisIPv4Address. Phone rejected the $Type request." Continue } } } } END { } } Function Reset-UcsRestConfiguration { <# .SYNOPSIS Restores a phone's configuration to defaults. .PARAMETER IPv4Address The network address in IPv4 notation, such as 192.123.45.67. .PARAMETER ToFactoryDefaults Specify that the phone should be returned to factory defaults. Note: The available information does not specify the difference between the normal behavior and "ToFactoryDefaults." #> [CmdletBinding(SupportsShouldProcess,ConfirmImpact = 'High')] Param([Parameter(Mandatory,HelpMessage = '127.0.0.1',ValueFromPipelineByPropertyName,ValueFromPipeline)][ValidatePattern('^([0-2]?[0-9]{1,2}\.){3}([0-2]?[0-9]{1,2})$')][String[]]$IPv4Address, [Switch]$ToFactoryDefaults, [String][ValidateSet('Local','Web','Device')]$ResetConfiguration = "All", [Int][ValidateRange(1,100)]$Retries = (Get-UcsConfig -Api REST).Retries) BEGIN { #$OutputArray = New-Object -TypeName System.Collections.ArrayList } PROCESS { foreach ($ThisIPv4Address in $IPv4Address) { if($PSCmdlet.ShouldProcess(('{0}' -f $ThisIPv4Address))) { Try { if($ToFactoryDefaults) { $ThisOutput = Invoke-UcsRestMethod -IPv4Address $ThisIPv4Address -ApiEndpoint 'api/v1/mgmt/factoryReset' -Method Post -Retries $Retries -ErrorAction Stop } else { if($ResetConfiguration -eq "All") { $ApiEndpoint = 'api/v1/mgmt/configReset' } else { $ApiEndpoint = ('api/v1/mgmt/configReset/{0}' -f $ResetConfiguration.ToLower()) } $ThisOutput = Invoke-UcsRestMethod -IPv4Address $ThisIPv4Address -ApiEndpoint $ApiEndpoint -Method Post -Retries $Retries -ErrorAction Stop } } Catch { Write-Debug -Message $_ Write-Error -Message "Couldn't reset $ThisIPv4Address to defaults. Could not connect to phone." } if($ThisOutput.Status.IsSuccess -ne $true) { Write-Debug -Message $ThisOutput.Status Write-Error -Message "Couldn't reset $ThisIPv4Address to defaults. An error occurred." Continue } } } } END { } } Function Get-UcsRestCall { <# .SYNOPSIS Returns call status. .DESCRIPTION Returns the current status of a call, including detailed information such as the directionality of the call, the call's handle, which can be used to take certain actions on the call, and other call-related details. If no calls is currently in progress, the cmdlet returns a warning and no output. Returns only one call regardless of the number of ongoing calls. .PARAMETER IPv4Address The network address in IPv4 notation, such as 192.123.45.67. .PARAMETER Quiet Prevents the API request from writing to the console. .EXAMPLE Get-CallStatus -IPv4Address 192.168.1.20 -Quiet Returns the call status of 192.168.1.20 but does not return warnings to the console in case of errors during API calls. #> Param([Parameter(Mandatory,HelpMessage = '127.0.0.1',ValueFromPipelineByPropertyName,ValueFromPipeline)][ValidatePattern('^([0-2]?[0-9]{1,2}\.){3}([0-2]?[0-9]{1,2})$')][String[]]$IPv4Address, [Switch]$Quiet, [Int][ValidateRange(1,100)]$Retries = (Get-UcsConfig -Api REST).Retries) BEGIN { $OutputArray = New-Object -TypeName System.Collections.ArrayList } PROCESS { foreach ($ThisIPv4Address in $IPv4Address) { Try { $ThisOutput = Invoke-UcsRestMethod -IPv4Address $ThisIPv4Address -ApiEndpoint 'api/v1/webCallControl/callStatus' -Retries $Retries -ErrorAction Stop } Catch { Write-Debug -Message "Error caught: $_." Write-Error -Message "Couldn't get call data from $ThisIPv4Address" Continue } Try { #5.7 uses "DurationSeconds" instead of "DurationInSeconds" #In 5.8, it returns to "DurationInSeconds" for the V1 API and the changes in V1 are implemented in the V2 API. if( ($ThisOutput.data | Get-Member -ErrorAction Stop).Name -contains 'DurationSeconds' ) { $CallDurationSeconds = $ThisOutput.data.DurationSeconds } else { $CallDurationSeconds = $ThisOutput.data.DurationInSeconds } } Catch { Write-Debug "No call in progress on $ThisIPv4Address." } if($null -ne $CallDurationSeconds) { $ThisCall = $ThisOutput.data Try { $PropertiesList = ($ThisCall | Get-Member -ErrorAction Stop).Name } Catch { Write-Debug "$ThisIPv4Address couldn't get a call." Continue } if($PropertiesList -contains 'UIAppearanceIndex') { if($ThisCall.UIAppearanceIndex -match '^\d+\*$') { $ActiveCall = $true } elseif ($ThisCall.UIAppearanceIndex -match '^\d+$') { $ActiveCall = $false } else { $ActiveCall = $null } $UIAppearanceIndex = $ThisCall.UiAppearanceIndex.Trim(' *') } if($ThisCall.StartTime.Length -gt 2) { $ThisStartTime = Get-Date $ThisCall.StartTime } else { $ThisStartTime = $null } if($null -ne $ThisCall.Muted) { $ThisCall.Muted = [Int]$ThisCall.Muted } if($null -ne $ThisCall.Ringing) { $ThisCall.Ringing = [Int]$ThisCall.Ringing } $ThisCallObject = New-UcsCallObject ` -Type $ThisCall.Type ` -CallHandle $ThisCall.CallHandle ` -Duration (New-TimeSpan -Seconds $CallDurationSeconds) ` -Protocol $ThisCall.Protocol.ToUpper() ` -CallState $ThisCall.CallState ` -RemotePartyName $ThisCall.RemotePartyName ` -LineId $ThisCall.LineId ` -RemotePartyNumber $ThisCall.RemotePartyNumber ` -Muted $ThisCall.Muted ` -Ringing $ThisCall.Muted ` -CallSequence $ThisCall.CallSequence ` -UIAppearanceIndex $UIAppearanceIndex ` -ActiveCall $ActiveCall ` -RTPPort $ThisCall.RTPPort ` -RTCPPort $ThisCall.RTCPPort ` -StartTime $ThisStartTime ` -IPv4Address $ThisIPv4Address ` -ExcludeNullProperties $null = $OutputArray.Add($ThisCallObject) } } } END { Return $OutputArray } } Function Get-UcsRestCallv2 { <# .SYNOPSIS Returns call status. .DESCRIPTION Returns the current status of a call, including detailed information such as the directionality of the call, the call's handle, which can be used to take certain actions on the call, and other call-related details. If no calls is currently in progress, the cmdlet returns a warning and no output. Returns only one call regardless of the number of ongoing calls. .PARAMETER IPv4Address The network address in IPv4 notation, such as 192.123.45.67. .PARAMETER Quiet Prevents the API request from writing to the console. .EXAMPLE Get-CallStatus -IPv4Address 192.168.1.20 -Quiet Returns the call status of 192.168.1.20 but does not return warnings to the console in case of errors during API calls. .NOTES Tested only in Skype for Business environment. #> [CmdletBinding(DefaultParameterSetName='DefaultParameterSet')] Param([Parameter(Mandatory,HelpMessage = '127.0.0.1',ValueFromPipelineByPropertyName,ValueFromPipeline)][ValidatePattern('^([0-2]?[0-9]{1,2}\.){3}([0-2]?[0-9]{1,2})$')][String[]]$IPv4Address, [Switch]$Quiet, [Parameter(Mandatory,ValueFromPipelineByPropertyName,ParameterSetName='CallHandleFilter')][String][ValidatePattern('^0x[a-f0-9]{7,8}$')]$CallHandle, [Parameter(Mandatory,ParameterSetName='SequenceFilter')][Parameter(Mandatory,ParameterSetName='LineFilter')][Int]$LineID, [Parameter(ParameterSetName='SequenceFilter',Mandatory)][Int]$CallSequence, [Int][ValidateRange(1,100)]$Retries = (Get-UcsConfig -Api REST).Retries) BEGIN { $OutputArray = New-Object -TypeName System.Collections.ArrayList } PROCESS { foreach ($ThisIPv4Address in $IPv4Address) { $ApiEndpointString = 'api/v2/webCallControl/callStatus' if($PSCmdlet.ParameterSetName -eq 'CallHandleFilter') { $ThisCallHandle = $CallHandle.Substring(2) #API wants the part after "Ox," so we remove it. $ApiEndpointString += "?handle=$ThisCallHandle" } elseif($PSCmdlet.ParameterSetName -eq 'LineFilter') { $ApiEndpointString += "?line=$LineID" } elseif($PSCmdlet.ParameterSetName -eq 'SequenceFilter') { $ApiEndpointString += "?line=$LineID&sequence=$CallSequence" } Try { $ThisOutput = Invoke-UcsRestMethod -IPv4Address $ThisIPv4Address -ApiEndpoint $ApiEndpointString -Retries $Retries -ErrorAction Stop } Catch { Write-Debug -Message "Error caught: $_." Write-Error -Message "Couldn't get call data from $ThisIPv4Address" Continue } foreach($ThisCall in $ThisOutput.Data) { $CallDurationSeconds = [Int]$ThisCall.DurationSeconds if($CallDurationSeconds -ne $null) { if($ThisCall.StartTime.Length -gt 2) { $ThisStartTime = Get-Date $ThisCall.StartTime } else { $ThisStartTime = $null } if($null -ne $ThisCall.Muted) { $ThisCall.Muted = [Int]$ThisCall.Muted } if($null -ne $ThisCall.Ringing) { $ThisCall.Ringing = [Int]$ThisCall.Ringing } $ThisCallObject = New-UcsCallObject ` -Type $ThisCall.Type ` -CallHandle $ThisCall.CallHandle ` -Duration (New-TimeSpan -Seconds $CallDurationSeconds) ` -Protocol $ThisCall.Protocol.ToUpper() ` -CallState $ThisCall.CallState ` -RemotePartyName $ThisCall.RemotePartyName ` -LineId $ThisCall.LineId ` -RemotePartyNumber $ThisCall.RemotePartyNumber ` -Muted $ThisCall.Muted ` -Ringing $ThisCall.Ringing ` -CallSequence $ThisCall.CallSequence ` -UIAppearanceIndex $ThisCall.UiAppearanceIndex ` -RTPPort $ThisCall.RTPPort ` -RTCPPort $ThisCall.RTCPPort ` -StartTime $ThisStartTime ` -IPv4Address $ThisIPv4Address $null = $OutputArray.Add($ThisCallObject) } } } } END { Return $OutputArray } } Function Get-UcsRestPresence { <# .SYNOPSIS Returns presence information from the phone, if supported by the call server. .DESCRIPTION Returns the user's current presence as shown by the phone. Phone output has been modified to simplify parsing of status. .PARAMETER IPv4Address The phone's IP address in standard format: 192.168.1.20 .EXAMPLE Get-Presence -IPv4Address 192.168.1.20 Returns the presence of the phone at the specified IP address. .NOTES Tested only in Skype for Business environment. #> Param([Parameter(Mandatory,HelpMessage = '127.0.0.1',ValueFromPipelineByPropertyName,ValueFromPipeline)][ValidatePattern('^([0-2]?[0-9]{1,2}\.){3}([0-2]?[0-9]{1,2})$')][String[]]$IPv4Address, [Int][ValidateRange(1,100)]$Retries = (Get-UcsConfig -Api REST).Retries) BEGIN { $OutputArray = New-Object -TypeName System.Collections.ArrayList } PROCESS { foreach ($ThisIPv4Address in $IPv4Address) { Try { $ThisOutput = Invoke-UcsRestMethod -IPv4Address $ThisIPv4Address -ApiEndpoint 'api/v1/mgmt/getPresence' -Retries $Retries -ErrorAction Stop } Catch { Write-Debug -Message "Caught error $_." Write-Error -Message "Couldn't get presence data from $ThisIPv4Address." Continue } if($null -ne $ThisOutput) { $Modified = $ThisOutput $Modified = $Modified | Select-Object -Property Presence, @{ Name = 'IPv4Address' Expression = { $ThisIPv4Address } } $null = $OutputArray.Add($Modified) } } } END { Return $OutputArray } } Function Get-UcsRestLineInfo { <# .SYNOPSIS Returns basic device information. .DESCRIPTION The LineInfo object includes information on the currently signed in user. .PARAMETER IPv4Address The network address in IPv4 notation, such as 192.123.45.67. .PARAMETER Quiet Prevents the API request from writing to the console. .EXAMPLE Get-LineInfo -IPv4Address 192.168.1.20 -Quiet LineNumber : 1 ProxyAddress : fakecompany.org Registered : True Label : John Smith LineType : private SIPAddress : sip:jsmith@fakecompany.org Protocol : SIP UserID : John Sminth Port : 0 IPv4Address : 192.168.1.20 .NOTES Behavior has not been tested in open SIP mode. #> Param([Parameter(Mandatory,HelpMessage = '127.0.0.1',ValueFromPipelineByPropertyName,ValueFromPipeline)][ValidatePattern('^([0-2]?[0-9]{1,2}\.){3}([0-2]?[0-9]{1,2})$')][String[]]$IPv4Address, [Switch]$Quiet, [Int][ValidateRange(1,100)]$Retries = (Get-UcsConfig -Api REST).Retries) BEGIN { $OutputArray = New-Object -TypeName System.Collections.ArrayList } PROCESS { foreach ($ThisIPv4Address in $IPv4Address) { Try { $ThisOutput = Invoke-UcsRestMethod -IPv4Address $ThisIPv4Address -ApiEndpoint 'api/v1/mgmt/lineInfo' -Retries $Retries -ErrorAction Stop } Catch { Write-Error -Message "Couldn't get line info from $ThisIPv4Address." Continue } if($null -ne $ThisOutput) { Foreach($Modified in $ThisOutput.data) { if($Modified.RegistrationStatus -eq 'registered') { $Registered = $true } elseif($Modified.RegistrationStatus -eq 'unregistered') { $Registered = $false } else { $Registered = $null } if( ($Modified | Get-Member).Name -contains 'Username') { #5.7.0 format $SipAddress = $Modified.Username } else { if($Modified.SIPAddress -notmatch '^.+@.+\..+$') { #For consistency of output, we don't want this to give us a fake SIP address if the phone is unregistered. $SIPAddress = $null } else { $SIPAddress = $Modified.SIPAddress } } if($null -ne $SipAddress) { $SipAddress = ('sip:{0}' -f $SipAddress) } $Modified = $Modified | Select-Object -ExcludeProperty Username,SipAddress,RegistrationStatus -Property *, @{ Name = 'Registered' Expression = { $Registered } }, @{ Name = 'SIPAddress' Expression = { $SIPAddress } }, @{ Name = 'IPv4Address' Expression = { $ThisIPv4Address } } $null = $OutputArray.Add($Modified) } } } } END { Return $OutputArray } } Function Get-UcsRestSipStatus { <# .SYNOPSIS Returns advanced SIP information. .PARAMETER IPv4Address The network address in IPv4 notation, such as 192.123.45.67 #> Param([Parameter(Mandatory,HelpMessage = '127.0.0.1',ValueFromPipelineByPropertyName,ValueFromPipeline)][ValidatePattern('^([0-2]?[0-9]{1,2}\.){3}([0-2]?[0-9]{1,2})$')][String[]]$IPv4Address, [Int][ValidateRange(1,100)]$Retries = (Get-UcsConfig -Api REST).Retries) BEGIN { $OutputArray = New-Object -TypeName System.Collections.ArrayList } PROCESS { foreach ($ThisIPv4Address in $IPv4Address) { $ThisOutput = Invoke-UcsRestMethod -IPv4Address $ThisIPv4Address -ApiEndpoint 'api/v1/webCallControl/sipStatus' -Retries $Retries if($null -ne $ThisOutput) { $Modified = $ThisOutput.data $Modified = $Modified | Select-Object -Property *, @{ Name = 'IPv4Address' Expression = { $ThisIPv4Address } } $null = $OutputArray.Add($Modified) } } } END { Return $OutputArray } } Function Get-UcsRestNetworkStatistic { <# .SYNOPSIS Returns basic device information. .PARAMETER IPv4Address The network address in IPv4 notation, such as 192.123.45.67. #> Param([Parameter(Mandatory,HelpMessage = '127.0.0.1',ValueFromPipelineByPropertyName,ValueFromPipeline)][ValidatePattern('^([0-2]?[0-9]{1,2}\.){3}([0-2]?[0-9]{1,2})$')][String[]]$IPv4Address, [Int][ValidateRange(1,100)]$Retries = (Get-UcsConfig -Api REST).Retries) BEGIN { $OutputArray = New-Object -TypeName System.Collections.ArrayList } PROCESS { foreach ($ThisIPv4Address in $IPv4Address) { Try { $ThisOutput = Invoke-UcsRestMethod -IPv4Address $ThisIPv4Address -ApiEndpoint 'api/v1/mgmt/network/stats' -Retries $Retries -ErrorAction Stop if($null -ne $ThisOutput) { $Modified = $ThisOutput.data $Modified = $Modified | Select-Object -Property *, @{ Name = 'IPv4Address' Expression = { $ThisIPv4Address } } $Modified.RxPackets = [Int32]$Modified.RxPackets $Modified.TxPackets = [Int32]$Modified.TxPackets $Modified.UpTime = Convert-UcsUptimeString -Uptime $Modified.Uptime $null = $OutputArray.Add($Modified) } } Catch { Write-Error "Couldn't connect to $ThisIPv4Address for network stats." } } } END { Return $OutputArray } } Function Start-UcsRestCall { <# .SYNOPSIS Dial a phone .PARAMETER IPv4Address The network address in IPv4 notation, such as 192.123.45.67. .PARAMETER Destination Call destination. SIP addresses work (no SIP prefix needed) or you could enter something like +15555551234@example.com. .PARAMETER LineId Which line number this call should be sent on. .PARAMETER CallType Which type of call this should be. Currently, only SIP is known as a valid option. .PARAMETER PassThru Return call status information. .EXAMPLE Start-PhoneCall -IPv4Address 192.168.1.2 -Destination "+15555551234@example.com" Initiates a call with the PSTN number 1-555-555-1234. #> Param([Parameter(Position = 1,Mandatory,HelpMessage = '127.0.0.1',ValueFromPipelineByPropertyName,ValueFromPipeline)][ValidatePattern('^([0-2]?[0-9]{1,2}\.){3}([0-2]?[0-9]{1,2})$')][String[]]$IPv4Address, [Parameter(Position = 2,Mandatory,HelpMessage = 'The call''s destination, such as +15555555555@example.com or example@example.com')][ValidatePattern('.+@.+\..+')][String]$Destination, [Parameter(Position = 3)][Int][ValidateRange(1,24)]$LineId = 1, [Parameter(Position = 4)][String][ValidateSet('SIP')]$CallType = 'SIP', [Parameter(Position = 5)][Switch]$PassThru, [Parameter(Position = 6)][Int][ValidateRange(1,100)]$Retries = (Get-UcsConfig -Api REST).Retries) BEGIN { $OutputArray = New-Object -TypeName System.Collections.ArrayList } PROCESS { foreach ($ThisIPv4Address in $IPv4Address) { $ThisDestination = $Destination $ThisDestination = Get-UcsCleanJSON -String $ThisDestination $DialString = ("{{`"data`":{{`"Dest`": `"{0}`",`"Line`": `"{1}`",`"Type`": `"{2}`"}}}}" -f $ThisDestination, $LineId, $CallType) Try { $ThisOutput = Invoke-UcsRestMethod -IPv4Address $ThisIPv4Address -ApiEndpoint 'api/v1/callctrl/dial' -Method Post -Body $DialString -Retries $Retries -ErrorAction Stop $ThisOutput = $ThisOutput.Status } Catch { Write-Error -Message "Couldn't start call to $ThisDestination on $ThisIPv4Address. Could not connect to phone." Continue } if($ThisOutput.IsSuccess -eq $true) { if($PassThru -eq $true) { Start-Sleep -Seconds 1 $ThisCall = Get-UcsRestCall -IPv4Address $IPv4Address $null = $OutputArray.Add($ThisCall) } } else { Write-Error -Message "Couldn't start call to $ThisDestination on $ThisIPv4Address. An error was returned from the phone." Continue } } } END { Return $OutputArray } } Function Stop-UcsRestCall { <# .SYNOPSIS Stop a phone call. .PARAMETER IPv4Address The network address in IPv4 notation, such as 192.123.45.67. .PARAMETER CallHandle Manually specify the callhandle to end. .PARAMETER Force Skip firmware version check. On certain firmware versions, calling Stop-UcsRestCall may cause the REST API to stop responding. #> [CmdletBinding(SupportsShouldProcess,ConfirmImpact = 'Medium')] Param([Parameter(Mandatory,HelpMessage = '127.0.0.1',ValueFromPipelineByPropertyName,ValueFromPipeline)][ValidatePattern('^([0-2]?[0-9]{1,2}\.){3}([0-2]?[0-9]{1,2})$')][String[]]$IPv4Address, [Parameter(ValueFromPipelineByPropertyName)][String][ValidatePattern('^0x[a-f0-9]{7,8}$')]$CallHandle, [Int][ValidateRange(1,100)]$Retries = (Get-UcsConfig -Api REST).Retries, [Switch]$Force) BEGIN { $OutputArray = New-Object -TypeName System.Collections.ArrayList } PROCESS { foreach ($ThisIPv4Address in $IPv4Address) { if($PSCmdlet.ShouldProcess(('{0}' -f $ThisIPv4Address))) { if($CallHandle -notmatch '^0x[a-f0-9]{7,8}$') { #This section attempts to get a call handle if one was not provided. if($CallHandle.Length -gt 0) { Write-Error -Message "Invalid call handle $CallHandle provided for $ThisIPv4Address." } else { Try { $CallStatus = Get-UcsRestCall -IPv4Address $ThisIPv4Address -ErrorAction Stop $CallHandle = $CallStatus.CallHandle } Catch { Write-Error -Message "Couldn't get call handle for $ThisIPv4Address." Continue } } } if($CallHandle.Length -gt 0) { #This section only starts if we have a callhandle. if($Force -ne $true) { #In certain 5.5.2 releases (5.5.2.8571 on VVX 310/311 tested), using the endCall endpoint causes a failure in the REST API. $DeviceInfo = Get-UcsRestDeviceInfo -IPv4Address $ThisIPv4Address if($DeviceInfo.FirmwareRelease -like '5.5.2.*') { Write-Error ('{0} is running firmware {1} which has a known issue with Stop-UcsRestCall. Use another API or use the Force parameter.' -f $ThisIPv4Address,$DeviceInfo.FirmwareRelease) Continue } } else { #Trying to be clear at the expense of technical accuracy. Write-Warning "Force was specified to end the call on $ThisIPv4Address. On some phones, ending a call with Force may cause the REST API to stop responding until the next reboot." } $CallHandle = Get-UcsCleanJSON -String $CallHandle $CallEndString = ('{{"data":{{"Ref": "{0}"}}}}' -f $CallHandle) Try { $ThisOutput = Invoke-UcsRestMethod -IPv4Address $ThisIPv4Address -ApiEndpoint 'api/v1/callctrl/endCall' -Body $CallEndString -Method Post -Retries $Retries -ErrorAction Stop } Catch { Write-Debug -Message "Caught error $_." Write-Error -Message "Couldn't end call $CallHandle for $ThisIPv4Address." Continue } $null = $OutputArray.Add($ThisOutput.Status) } else { Write-Warning -Message ('No call to end for {0}.' -f $ThisIPv4Address) } } } } END { Return $OutputArray } } Function Set-UcsRestCallMute { <# .SYNOPSIS Mute or unmute a call. .PARAMETER IPv4Address The network address in IPv4 notation, such as 192.123.45.67. .PARAMETER Mute Switch. If specified, mutes the call. #> [CmdletBinding(SupportsShouldProcess,ConfirmImpact = 'Medium')] Param([Parameter(Mandatory,HelpMessage = '127.0.0.1',ValueFromPipelineByPropertyName,ValueFromPipeline)][ValidatePattern('^([0-2]?[0-9]{1,2}\.){3}([0-2]?[0-9]{1,2})$')][String[]]$IPv4Address, [Switch]$Mute, [Int][ValidateRange(1,100)]$Retries = (Get-UcsConfig -Api REST).Retries) BEGIN { $OutputArray = New-Object -TypeName System.Collections.ArrayList } PROCESS { foreach ($ThisIPv4Address in $IPv4Address) { $MuteInt = 0 if($Mute) { $MuteInt = 1 } $CallMuteString = ('{{"data":{{"state": "{0}"}}}}' -f $MuteInt) Try { if($PSCmdlet.ShouldContinue($ThisIPv4Address,"Mute ongoing call?")) { $ThisOutput = Invoke-UcsRestMethod -IPv4Address $ThisIPv4Address -ApiEndpoint 'api/v1/callctrl/mute' -Body $CallMuteString -Method Post -Retries $Retries -ErrorAction Stop } } Catch { Write-Debug -Message "Caught error $_." Write-Error -Message "Couldn't mute for $ThisIPv4Address." Continue } $null = $OutputArray.Add($ThisOutput.Status) } } END { Return $OutputArray } } Function Start-UcsRestCallTransfer { <# .SYNOPSIS Transfer a phone call. .PARAMETER IPv4Address The network address in IPv4 notation, such as 192.123.45.67. .PARAMETER CallHandle Manually specify the callhandle to end. .PARAMETER Destination The transfer destination. Mandatory. #> [CmdletBinding(SupportsShouldProcess,ConfirmImpact = 'Medium')] Param([Parameter(Mandatory,HelpMessage = '127.0.0.1',ValueFromPipelineByPropertyName,ValueFromPipeline)][ValidatePattern('^([0-2]?[0-9]{1,2}\.){3}([0-2]?[0-9]{1,2})$')][String[]]$IPv4Address, [Parameter(ValueFromPipelineByPropertyName)][String][ValidatePattern('^0x[a-f0-9]{7,8}$')]$CallHandle, [Int][ValidateRange(1,100)]$Retries = (Get-UcsConfig -Api REST).Retries, [Parameter(Mandatory)]$Destination) BEGIN { $OutputArray = New-Object -TypeName System.Collections.ArrayList } PROCESS { foreach ($ThisIPv4Address in $IPv4Address) { if($PSCmdlet.ShouldProcess(('{0}' -f $ThisIPv4Address))) { if($CallHandle -notmatch '^0x[a-f0-9]{7,8}$') { #This section attempts to get a call handle if one was not provided. if($CallHandle.Length -gt 0) { Write-Error -Message "Invalid call handle $CallHandle provided for $ThisIPv4Address." } else { Try { $CallStatus = Get-UcsRestCall -IPv4Address $ThisIPv4Address -ErrorAction Stop $CallHandle = $CallStatus.CallHandle } Catch { Write-Error -Message "Couldn't get call handle for $ThisIPv4Address." Continue } } } if($CallHandle.Length -gt 0) { $CallHandle = Get-UcsCleanJSON -String $CallHandle $TransferString = ('{{"data":{{"Ref": "{0}","TransferDest":"{1}"}}}}' -f $CallHandle,$Destination) Try { $ThisOutput = Invoke-UcsRestMethod -IPv4Address $ThisIPv4Address -ApiEndpoint 'api/v1/callctrl/transferCall' -Body $TransferString -Method Post -Retries $Retries -ErrorAction Stop } Catch { Write-Debug -Message "Caught error $_." Write-Error -Message "Couldn't end call $CallHandle for $ThisIPv4Address." Continue } $null = $OutputArray.Add($ThisOutput.Status) } else { Write-Warning -Message ('No call to end for {0}.' -f $ThisIPv4Address) } } } } END { Return $OutputArray } } Function Send-UcsRestCallDTMF { <# .SYNOPSIS Send keypad commands. .PARAMETER IPv4Address The network address in IPv4 notation, such as 192.123.45.67. #> [CmdletBinding(SupportsShouldProcess,ConfirmImpact = 'Medium')] Param([Parameter(Mandatory,HelpMessage = '127.0.0.1',ValueFromPipelineByPropertyName,ValueFromPipeline)][ValidatePattern('^([0-2]?[0-9]{1,2}\.){3}([0-2]?[0-9]{1,2})$')][String[]]$IPv4Address, [Parameter(Mandatory)][ValidatePattern('^[0-9\#\*]+$')][String]$Digits, [Int][ValidateRange(1,100)]$Retries = (Get-UcsConfig -Api REST).Retries) BEGIN { $OutputArray = New-Object -TypeName System.Collections.ArrayList } PROCESS { foreach ($ThisIPv4Address in $IPv4Address) { $DTMFstring = ('{{"data":{{"Digits": "{0}"}}}}' -f $Digits) Try { if($PSCmdlet.ShouldContinue($ThisIPv4Address,"Send $Digits?")) { $ThisOutput = Invoke-UcsRestMethod -IPv4Address $ThisIPv4Address -ApiEndpoint 'api/v1/callctrl/sendDTMF' -Body $DTMFstring -Method Post -Retries $Retries -ErrorAction Stop } } Catch { Write-Debug -Message "Caught error $_." Write-Error -Message "Couldn't send DTMF for $ThisIPv4Address." Continue } $null = $OutputArray.Add($ThisOutput.Status) } } END { Return $OutputArray } } Function Get-UcsRestCallLog { <# .SYNOPSIS Get call logs from phone. .PARAMETER IPv4Address The network address in IPv4 notation, such as 192.123.45.67. .PARAMETER Filter Filter to missed, received, or placed. #> Param([Parameter(Mandatory,HelpMessage = '127.0.0.1',ValueFromPipelineByPropertyName,ValueFromPipeline)][ValidatePattern('^([0-2]?[0-9]{1,2}\.){3}([0-2]?[0-9]{1,2})$')][String[]]$IPv4Address, [ValidateSet('All','Missed','Incoming','Outgoing')][String]$Filter = 'All', [Int][ValidateRange(1,100)]$Retries = (Get-UcsConfig -Api REST).Retries) BEGIN { $OutputArray = New-Object -TypeName System.Collections.ArrayList $FilterMapping = @{'All'='all';'Missed'='missed';'Incoming'='received';'Outgoing'='placed'} } PROCESS { foreach ($ThisIPv4Address in $IPv4Address) { if($Filter -eq 'All') { $FilterString = 'api/v1/mgmt/callLogs' } else { $FilterString = ('api/v1/mgmt/callLogs/{0}' -f $FilterMapping[$Filter]) } Try { $ThisOutput = Invoke-UcsRestMethod -IPv4Address $ThisIPv4Address -ApiEndpoint $FilterString -Method Get -Retries $Retries -ErrorAction Stop } Catch { Write-Debug -Message "Caught error $_." Write-Error -Message "Couldn't get calls for $ThisIPv4Address." Continue } $AllCallList = New-Object System.Collections.ArrayList if($Filter -eq 'All') { $CallCategories = $ThisOutput.Data | Get-Member -MemberType NoteProperty | Select-Object -ExpandProperty Name Foreach($Category in $CallCategories) { Foreach($Call in $ThisOutput.Data.$Category) { $ThisCallType = $Category $null = $AllCallList.Add($Call) } } } else { Foreach($Call in $ThisOutput.Data) { $ThisCallType = $Filter $null = $AllCallList.Add($Call) } } Foreach($Call in $AllCallList) { $ThisCallObject = New-UcsCallObject ` -Type $ThisCallType ` -StartTime $Call.StartTime ` -RemotePartyName $Call.RemotePartyName ` -RemotePartyNumber $Call.RemotePartyNumber ` -LineId $Call.LineNumber ` -IPv4Address $ThisIPv4Address ` -ExcludeNullProperties $null = $OutputArray.Add($ThisCallObject) } } } END { Return $OutputArray } } Function Set-UcsRestCallHold { <# .SYNOPSIS Hold or resume a call. .PARAMETER IPv4Address The network address in IPv4 notation, such as 192.123.45.67. .PARAMETER Hold Boolean. If true, places the call on hold. If false, resumes a held call. #> [CmdletBinding(SupportsShouldProcess,ConfirmImpact = 'Medium')] Param([Parameter(Mandatory,HelpMessage = '127.0.0.1',ValueFromPipelineByPropertyName,ValueFromPipeline)][ValidatePattern('^([0-2]?[0-9]{1,2}\.){3}([0-2]?[0-9]{1,2})$')][String[]]$IPv4Address, [Boolean]$Hold = $true, [Parameter(ValueFromPipelineByPropertyName)][String][ValidatePattern('^0x[a-f0-9]{7,8}$')]$CallHandle, [Int][ValidateRange(1,100)]$Retries = (Get-UcsConfig -Api REST).Retries) BEGIN { $OutputArray = New-Object -TypeName System.Collections.ArrayList } PROCESS { foreach ($ThisIPv4Address in $IPv4Address) { if($CallHandle.Length -gt 4) { $CallRefString = ('{{"data":{{"Ref": "{0}"}}}}' -f [Int]$CallHandle) } else { $CallRefString = '' } Try { if($PSCmdlet.ShouldContinue($ThisIPv4Address,"Hold/Resume ongoing call?")) { if($Hold) { $ThisOutput = Invoke-UcsRestMethod -IPv4Address $ThisIPv4Address -ApiEndpoint 'api/v1/callctrl/holdCall' -Body $CallRefString -Method Post -Retries $Retries -ErrorAction Stop } else { $ThisOutput = Invoke-UcsRestMethod -IPv4Address $ThisIPv4Address -ApiEndpoint 'api/v1/callctrl/resumeCall' -Body $CallRefString -Method Post -Retries $Retries -ErrorAction Stop } } } Catch { Write-Debug -Message "Caught error $_." Write-Error -Message "Couldn't hold/resume for $ThisIPv4Address." Continue } $null = $OutputArray.Add($ThisOutput.Status) } } END { Return $OutputArray } } Function Start-UcsRestCallAnswer { <# .SYNOPSIS Take an action on a current ringing call. .PARAMETER IPv4Address The network address in IPv4 notation, such as 192.123.45.67. .PARAMETER CallHandle Optional. If specified, answers the specified call. .PARAMETER Ignore Switch. If specified, call is ignored instead of answered. .PARAMETER Reject Switch. If specified, call is rejected instead of answered. Takes precedence over Ignore. #> [CmdletBinding(SupportsShouldProcess,ConfirmImpact = 'Medium')] Param([Parameter(Mandatory,HelpMessage = '127.0.0.1',ValueFromPipelineByPropertyName,ValueFromPipeline)][ValidatePattern('^([0-2]?[0-9]{1,2}\.){3}([0-2]?[0-9]{1,2})$')][String[]]$IPv4Address, [Parameter(ValueFromPipelineByPropertyName)][String][ValidatePattern('^0x[a-f0-9]{7,8}$')]$CallHandle, [Switch]$Ignore, [Switch]$Reject, [Int][ValidateRange(1,100)]$Retries = (Get-UcsConfig -Api REST).Retries) BEGIN { $OutputArray = New-Object -TypeName System.Collections.ArrayList } PROCESS { foreach ($ThisIPv4Address in $IPv4Address) { if($CallHandle.Length -gt 4) { $CallRefString = ('{{"data":{{"Ref": "{0}"}}}}' -f [Int]$CallHandle) } else { $CallRefString = '' } Try { if($PSCmdlet.ShouldContinue($ThisIPv4Address,"Take action on inbound call?")) { if($Reject) { $ThisOutput = Invoke-UcsRestMethod -IPv4Address $ThisIPv4Address -ApiEndpoint 'api/v1/callctrl/rejectCall' -Body $CallRefString -Method Post -Retries $Retries -ErrorAction Stop } elseif($Ignore) { $ThisOutput = Invoke-UcsRestMethod -IPv4Address $ThisIPv4Address -ApiEndpoint 'api/v1/callctrl/ignoreCall' -Body $CallRefString -Method Post -Retries $Retries -ErrorAction Stop } else { $ThisOutput = Invoke-UcsRestMethod -IPv4Address $ThisIPv4Address -ApiEndpoint 'api/v1/callctrl/answerCall' -Body $CallRefString -Method Post -Retries $Retries -ErrorAction Stop } } } Catch { Write-Debug -Message "Caught error $_." Write-Error -Message "Couldn't answer for $ThisIPv4Address." Continue } $null = $OutputArray.Add($ThisOutput.Status) } } END { Return $OutputArray } } Function Get-UcsRestStatus { <# .SYNOPSIS Polls for idle/active/error state .PARAMETER IPv4Address The phone's IP address in standard format: 192.168.1.20 .EXAMPLE Get-Presence -IPv4Address 192.168.1.20 Returns the presence of the phone at the specified IP address. #> Param([Parameter(Mandatory,HelpMessage = '127.0.0.1',ValueFromPipelineByPropertyName,ValueFromPipeline)][ValidatePattern('^([0-2]?[0-9]{1,2}\.){3}([0-2]?[0-9]{1,2})$')][String[]]$IPv4Address, [Int][ValidateRange(1,100)]$Retries = (Get-UcsConfig -Api REST).Retries) BEGIN { $OutputArray = New-Object -TypeName System.Collections.ArrayList } PROCESS { foreach ($ThisIPv4Address in $IPv4Address) { Try { $ThisOutput = Invoke-UcsRestMethod -IPv4Address $ThisIPv4Address -ApiEndpoint 'api/v1/mgmt/pollForStatus' -Retries $Retries -ErrorAction Stop } Catch { Write-Debug -Message "Caught error $_." Write-Error -Message "Couldn't get status data from $ThisIPv4Address." Continue } if($null -ne $ThisOutput) { $Modified = $ThisOutput.data $Duration = $null $TimeofLastCall = $null $ErrorString = $null if($Modified.State -eq "Active") { #We're in a call. Provision a "duration" property. $DurationString = $Modified.StateData.Replace('Active call duration','').Trim() $Duration = Convert-UcsRestDuration -Duration $DurationString } elseif($Modified.State -eq "Idle") { #No call in progress. Provision a "Time since last call" property. $LastCallString = $Modified.StateData.Replace('Time of last call','').Trim() $TimeofLastCall = Get-Date $LastCallString } else { #Probably an error. $ErrorString = $Modified.StateData } $Modified = $Modified | Select-Object -Property State,@{Name='Duration';Expression={$Duration}},@{Name='TimeOfLastCall';Expression={$TimeOfLastCall}},@{Name='ErrorString';Expression={$ErrorString}},@{ Name = 'IPv4Address' Expression = { $ThisIPv4Address } } $null = $OutputArray.Add($Modified) } } } END { Return $OutputArray } } Function Start-UcsRestPacketCapture { <# .SYNOPSIS Begin uploading captured network packets to a specified URL. .DESCRIPTION Upload captured network packets to a provisioning server or other location. If unspecified, the phone uploads to its provisioning server. There is no way to end a background packet capture explicitly. .PARAMETER IPv4Address The phone's IP address in standard format: 192.168.1.20 .NOTES May require additional configuration, including enabling diags.pcap.enabled and diags.pcap.background.enabled. See Polycom documentation for details. #> Param([Parameter(Mandatory,HelpMessage = '127.0.0.1',ValueFromPipelineByPropertyName,ValueFromPipeline)][ValidatePattern('^([0-2]?[0-9]{1,2}\.){3}([0-2]?[0-9]{1,2})$')][String[]]$IPv4Address, [String]$URL = $null, [Int][ValidateRange(1,100)]$Retries = (Get-UcsConfig -Api REST).Retries) BEGIN { } PROCESS { foreach ($ThisIPv4Address in $IPv4Address) { Try { if($null -eq $URL) { $null = Invoke-UcsRestMethod -IPv4Address $ThisIPv4Address -ApiEndpoint 'api/v1/mgmt/network/uploadBgCapture' -Retries $Retries -Method Post -ErrorAction Stop } else { $URLBody = ('{{"data":{{"url": "{0}"}}}}' -f $URL) $null = Invoke-UcsRestMethod -IPv4Address $ThisIPv4Address -ApiEndpoint 'api/v1/mgmt/network/uploadBgCapture' -Body $URLBody -Retries $Retries -Method Post -ErrorAction Stop } } Catch { Write-Debug -Message "Caught error $_." Write-Error -Message "Couldn't start capturing packets from $ThisIPv4Address." Continue } } } END { } } Function Get-UcsRestDeviceStatistic { <# .SYNOPSIS Returns device hardware statistics. .DESCRIPTION Provides hardware statistics directly from the phone's API. The Cmdlet currently doesn't provide any cleanup of values. .PARAMETER IPv4Address The network address in IPv4 notation, such as 192.123.45.67. #> Param([Parameter(Mandatory,HelpMessage = '127.0.0.1',ValueFromPipelineByPropertyName,ValueFromPipeline)][ValidatePattern('^([0-2]?[0-9]{1,2}\.){3}([0-2]?[0-9]{1,2})$')][String[]]$IPv4Address, [Int][ValidateRange(1,100)]$Retries = (Get-UcsConfig -Api REST).Retries) BEGIN { } PROCESS { foreach ($ThisIPv4Address in $IPv4Address) { Try { $ThisOutput = Invoke-UcsRestMethod -IPv4Address $ThisIPv4Address -ApiEndpoint 'api/v1/mgmt/device/stats' -Retries $Retries -ErrorAction Stop $ThisOutput.data | Select-Object *,@{Name="IPv4Address";Expression={$ThisIPv4Address}} } Catch { Write-Error "Couldn't connect to $ThisIPv4Address for device stats." } } } END { } } Function Register-UcsRestLyncUser { <# .SYNOPSIS Sign in a Skype/Lync user to the phone. .PARAMETER IPv4Address The network address in IPv4 notation, such as 192.123.45.67. .PARAMETER Credential The username and password for the account. .PARAMETER Address Sign-in address, such as jsmith@company.com .PARAMETER LockCode Optional, specify a code to be used when unlocking the phone. .NOTE The default timeout for this cmdlet is 155 seconds. #> [CmdletBinding(SupportsShouldProcess,ConfirmImpact = 'Medium')] Param([Parameter(Mandatory,HelpMessage = '127.0.0.1',ValueFromPipelineByPropertyName,ValueFromPipeline)][ValidatePattern('^([0-2]?[0-9]{1,2}\.){3}([0-2]?[0-9]{1,2})$')][String[]]$IPv4Address, [Parameter(Mandatory,HelpMessage='jsmith@company.com')][String]$Address, [Parameter(Mandatory,HelpMessage='A credential corresponding to the sign-in address already provided.')][PsCredential]$Credential, [String]$Domain = $null, [Int]$LockCode = $null, [Int][ValidateRange(1,100)]$Retries = (Get-UcsConfig -Api REST).Retries, [ValidateRange(1,1000)][Int]$Timeout = 155 ) BEGIN { } PROCESS { foreach ($ThisIPv4Address in $IPv4Address) { Try { if($null -eq $LockCode) { $SignInString = ('{{"data":{{"Address": "{0}","User": "{1}","Password": "{2}","Domain": "{3}"}}}}' -f $Address,$Credential.UserName,(ConvertFrom-PsCredential -Credential $Credential),$Domain) } else { $SignInString = ('{{"data":{{"Address": "{0}","User": "{1}","Password": "{2}","Domain": "{3}","LockCode": "{4}"}}}}' -f $Address,$Credential.UserName,(ConvertFrom-PsCredential -Credential $Credential),$Domain,$LockCode) } if ($PSCmdlet.ShouldContinue($ThisIPv4Address)) { $null = Invoke-UcsRestMethod -IPv4Address $ThisIPv4Address -ApiEndpoint 'api/v1/mgmt/skype/signIn' -Body $SignInString -Method Post -Retries $Retries -Timeout $Timeout -ErrorAction Stop } } Catch { Write-Debug -Message "Caught error $_." Write-Error -Message "Couldn't sign-in for $ThisIPv4Address." Continue } } } END { } } Function Unregister-UcsRestLyncUser { <# .SYNOPSIS Sign out a Skype/Lync user. .PARAMETER IPv4Address The network address in IPv4 notation, such as 192.123.45.67. .NOTE The default timeout for this cmdlet is 20 seconds. #> [CmdletBinding(SupportsShouldProcess,ConfirmImpact = 'High')] Param([Parameter(Mandatory,HelpMessage = '127.0.0.1',ValueFromPipelineByPropertyName,ValueFromPipeline)][ValidatePattern('^([0-2]?[0-9]{1,2}\.){3}([0-2]?[0-9]{1,2})$')][String[]]$IPv4Address, [Int][ValidateRange(1,100)]$Retries = (Get-UcsConfig -Api REST).Retries, [ValidateRange(1,1000)][Int]$Timeout = 155 ) BEGIN { } PROCESS { foreach ($ThisIPv4Address in $IPv4Address) { if ($PSCmdlet.ShouldProcess($ThisIPv4Address)) { Try { $null = Invoke-UcsRestMethod -IPv4Address $ThisIPv4Address -ApiEndpoint 'api/v1/mgmt/skype/signOut' -Method Post -Retries $Retries -Timeout $Timeout -ErrorAction Stop } Catch { Write-Debug -Message "Caught error $_." Write-Error -Message "Couldn't sign out $ThisIPv4Address." Continue } } } } END { } } Function Get-UcsRestLocationInfo { <# .SYNOPSIS Returns device location information. .DESCRIPTION Provides location info directly from the phone's API. The Cmdlet currently doesn't provide any cleanup of values. .PARAMETER IPv4Address The network address in IPv4 notation, such as 192.123.45.67. #> Param([Parameter(Mandatory,HelpMessage = '127.0.0.1',ValueFromPipelineByPropertyName,ValueFromPipeline)][ValidatePattern('^([0-2]?[0-9]{1,2}\.){3}([0-2]?[0-9]{1,2})$')][String[]]$IPv4Address, [Int][ValidateRange(1,100)]$Retries = (Get-UcsConfig -Api REST).Retries) BEGIN { } PROCESS { foreach ($ThisIPv4Address in $IPv4Address) { Try { $ThisOutput = Invoke-UcsRestMethod -IPv4Address $ThisIPv4Address -ApiEndpoint 'api/v1/mgmt/location/info' -Method Get -Retries $Retries -ErrorAction Stop $ThisOutput.data | Select-Object *,@{Name="IPv4Address";Expression={$ThisIPv4Address}} } Catch { Write-Error "Couldn't connect to $ThisIPv4Address for location info." } } } END { } } |