public/Networks.ps1
using namespace System.Collections.Generic #Meraki Network Functions #region Networks function Get-MerakiNetwork() { Param( [Parameter( Mandatory = $true )] [String]$networkID ) $Uri = "{0}/networks/{1}" -f $BaseURI, $networkID $Headers = Get-Headers try { $Response = Invoke-RestMethod -Method GET -Uri $Uri -Headers $Headers -PreserveAuthorizationOnRedirect return $Response } catch { throw $_ } <# .SYNOPSIS Returns a Meraki Network. .PARAMETER networkID The ID of the network. .OUTPUTS A Meraki network object. #> } Set-Alias -Name GMNet -Value Get-MerakiNetwork -Option:ReadOnly function Set-MerakiNetwork() { [CmdletBinding()] Param( [Parameter(Mandatory = $true)] [string]$NetworkId, [Parameter(Mandatory = $true)] [string]$Name, [string]$TimeZone, [string]$Notes, [string[]]$Tags, [string]$EnrollmentString ) $Headers = Get-Headers $Uri = "{0}/networks/{1}" -f $BaseURI, $NetworkId $_body = @{} if ($Name) { $_body.Add("name", $Name) } if ($TimeZone) { $_body.Add("timeZone", $TimeZone) } if ($Notes) { $_body.Add("notes", $Notes) } if ($Tags) { $_body.Add("tags", $Tags) } if ($EnrollmentString) { $_body.Add("enrollmentString", $EnrollmentString) } $body = $_body | ConvertTo-Json -Depth 5 -Compress try { $response = Invoke-RestMethod -Method Put -Uri $Uri -Headers $Headers -Body $body -PreserveAuthorizationOnRedirect return $response } catch { throw $_ } <# .SYNOPSIS Modify a network .DESCRIPTION Modify settings on a Meraki Network .PARAMETER NetworkId The ID of the network .PARAMETER Name The name of the network .PARAMETER TimeZone The timezone of the network. For a list of allowed timezones .PARAMETER Notes Add any notes or additional information about this network here .PARAMETER Tags A list of tags to be applied to the network .PARAMETER EnrollmentString A unique identifier which can be used for device enrollment or easy access through the Meraki SM Registration page or the Self Service Portal. Please note that changing this field may cause existing bookmarks to break. .OUTPUTS A network object #> } function Connect-MerakiNetworkToTemplate() { [CmdletBinding()] Param( [Parameter(Mandatory = $true)] [string]$NetworkId, [Parameter(Mandatory = $true)] [string]$ConfigTemplateId, [switch]$AutoBind ) $Headers = Get-Headers $Uri = $"{0}/networks/{1}/bind" -f $NetworkId $Template = Get-MerakiOrganizationConfigTemplate -ConfigTemplateId $ConfigTemplateId if (-not $Template) { throw "Invalid ConfigTemplateId" } $_Body = @{ "configTemplateId" = $ConfigTemplateId "autoBind" = $AutoBind.IsPresent } $body = $_Body | ConvertTo-Json -Compress try { $response = Invoke-RestMethod -Method GET -Uri $Uri -Headers $Headers -Body $body -PreserveAuthorizationOnRedirect return $response } catch { throw $_ } <# .SYNOPSIS Connect a template to a network .DESCRIPTION Connect a Meraki network to a configuration template .PARAMETER NetworkId The Id of the network to connect .PARAMETER ConfigTemplateId The Id of the configuration template .PARAMETER AutoBind Optional boolean indicating whether the network's switches should automatically bind to profiles of the same model. Defaults to false if left unspecified. This option only affects switch networks and switch templates. Auto-bind is not valid unless the switch template has at least one profile and has at most one profile per switch model. .OUTPUTS A network object #> } function Disconnect-MerakiNetworkFromTemplate() { [CmdletBinding()] Param( [Parameter(Mandatory = $true)] [string]$NetworkId, [switch]$RetainConfigs ) $Header = Get-Headers $Uri = "{0}/networks/{1}/unbind" -f $BaseURI, $NetworkId if ($RetainConfigs.IsPresent) { $body = @{"retainConfigs" = "true"} | ConvertTo-Json -Compress } try { $response = Invoke-RestMethod -Method POST -Uri $Uri -Headers $Header -Body $body -PreserveAuthorizationOnRedirect return $response } catch { throw $_ } <# .SYNOPSIS Disconnect a network from a template .DESCRIPTION Disconnect a Meraki Network from a configuration template .PARAMETER NetworkId The ID of the network .PARAMETER RetainConfigs Optional boolean to retain all the current configs given by the template .OUTPUTS A network object #> } function Merge-MerakiNetworks() { [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'default')] Param( [Parameter(Mandatory = $true)] [string]$Name, [Parameter( Mandatory, ValueFromPipelineByPropertyName )] [Alias('NetworkId')] [string]$Id, [string]$EnrollmentString, [Parameter(ParameterSetName = 'org')] [string]$OrgID, [Parameter(ParameterSetName = 'profile')] [string]$profileName ) <# if ($OrgID -and $profileName) { Write-Host "The OrgId and ProfileName parameters cannot be used together." -ForegroundColor Red return } #> Begin { if (-not $OrgID) { $config = Read-Config if ($profileName) { $OrgID = $config.profiles.$profileName if (-not $OrgID) { throw "Invalid profile name!" } } else { $OrgID = $config.profiles.default } } $Networks = [List[string]]::New() $Header = Get-Headers $Uri = "{0}/organizations/{1}/networks/combine" -f $BaseURI, $OrgID } Process { $Networks.Add($Id) } End { $_Body = @{ "name" = $Name "networkIds" = ($Networks.ToArray()) } if ($EnrollmentString) { $_Body.Add("enrollmentString", $EnrollmentString) } $body = $_Body | ConvertTo-Json -Compress if ($PSCmdlet.ShouldProcess('Merge',"Networks $($Networks -join ',')")) { try { $response = Invoke-RestMethod -Method POST -Uri $Uri -Headers $Header -Body $Body -PreserveAuthorizationOnRedirect return $response } catch { throw $_ } } } <# .SYNOPSIS Combine multiple networks into a single network. .DESCRIPTION Combine multiple Meraki networks into a single network. .PARAMETER Name The name of the combined network. .PARAMETER NetworkIds A list of the network IDs that will be combined. If an ID of a combined network is included in this list, the other networks in the list will be grouped into that network. .PARAMETER EnrollmentString A unique identifier which can be used for device enrollment or easy access through the Meraki SM Registration page or the Self Service Portal. Please note that changing this field may cause existing bookmarks to break. All networks that are part of this combined network will have their enrollment string appended by '-network_type'. If left empty, all existing enrollment strings will be deleted. .PARAMETER OrgID The Organization ID .PARAMETER profileName The saved Profile name. .OUTPUTS A network object #> } function Split-MerakiNetwork() { [CmdletBinding(SupportsShouldProcess)] Param( [Parameter(Mandatory = $true)] [string]$NetworkId ) $Header = Get-Headers $Uri = "{0}/networks/{1}/split" -f $BaseURI, $NetworkId $Network = Get-MerakiNetwork -networkID $NetworkId if ($PSCmdlet.ShouldProcess('Split',"Network $($Network.NAme)")) { try { $response = Invoke-RestMethod -Method POST -Uri $Uri -Headers $Header -PreserveAuthorizationOnRedirect return $response } catch { throw $_ } } <# .SYNOPSIS Split network into individual networks .DESCRIPTION Split a combined network into individual networks for each type of device .PARAMETER NetworkId The Id of then network .OUTPUTS An array of network objects #> } #endregion function Get-MerakiNetworkDevices () { [CmdletBinding()] Param ( [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $True)] [string]$id ) Begin { $Headers = Get-Headers } Process { $Uri = "{0}/networks/{1}/devices" -f $BaseURI, $id try { $response = Invoke-RestMethod -Method GET -Uri $Uri -Headers $Headers -PreserveAuthorizationOnRedirect return $response } catch { throw $_ } } <# .SYNOPSIS Get the Network Devices for a Network. .PARAMETER id The Network ID. .OUTPUTS An array of network devices. #> } Set-Alias -Name GMNetDevs -Value Get-MerakiNetworkDevices -Option ReadOnly function Get-MerakiNetworkEvents() { [CmdletBinding()] Param( [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true )] [string]$id, [Parameter( Mandatory = $true )] [ValidateSet('wireless','appliance','switches','systemManager','camera','cellularGateway')] [string]$ProductType, [string[]]$IncludedEventTypes, [string[]]$ExcludedEventTypes, [string]$deviceMac, [string]$deviceName, [string]$deviceSerial, [string]$clientName, [string]$clientIP, [string]$clientMac, [string]$smDeviceName, [string]$smDeviceMac, [ValidateScript({$_ -is [int]})] [ValidateSet(3,1000)] [int]$PerPage, [int]$Pages = 1 ) Begin { $Headers = Get-Headers if ($PerPage) { $Query = "perPage={0}" -f $PerPage } if ($IncludedEventTypes) { if ($Query) {$Query += '&'} $Query = "{0}includedEventTypes[]={1}" -f $Query, ($IncludedEventTypes -join ',') } if ($ExcludedEventTypes) { if ($Query) {$Query += '&'} $Query = "{0}excludedEventTypes[]={1}" -f $Query, ($ExcludedEventTypes -join ',') } if ($deviceMac) { if ($Query) {$Query += '&'} $Query = "{0}deviceMac={1}" -f $Query, $deviceMac } if ($deviceSerial) { if ($Query) {$Query += '&'} $Query = "{0}deviceSerial={1}" -f $Query, $deviceSerial } if ($clientIP) { if ($Query) {Query += '&'} $Query = "{0}deviceIP={1}" -f $Query, $deviceSerial } if ($smDeviceMac) { if ($Query) {$Query += '&'} $Query = "{0}smDeviceMac={1}" -f $Query, $smDeviceMac } if ($smDeviceName) { if ($Query) {$Query += '&'} $Query = "{0}smDeviceName={1}" -f $Query, $smDeviceName } $Results = [List[PsObject]]::New() } Process { $Uri = "{0}/networks/{1}/events" -f $BaseURI, $id try { $response = Invoke-WebRequest -Method GET -Uri $Uri -Body $body -Headers $Headers -PreserveAuthorizationOnRedirect [List[PsObject]]$result = $response.Content | ConvertFrom-Json if ($result) { $Result.AddRange($result) } $page = 1 if ($Pages -ne 1) { $done = $false do { if ($response.RelationLink['next']) { $Uri = $response.RelationLink['next'] $response = Invoke-WebRequest -Method Get -Uri $Uri -Headers $Headers -PreserveAuthorizationOnRedirect [List[PsObject]]$result = $response.Content | ConvertFrom-Json if ($result) { $Results.AddRange($result) } $page += 1 if ($page -gt $Pages) { $done = $true } } else { $done = $true } } until ($done) } return $Results.ToArray() | Sort-Object occurredAt } catch { throw $_ } } <# .SYNOPSIS Returns Network Event. .Description Returns network events for this network. .PARAMETER id The network Id. .PARAMETER ProductType The product type to pull events for. .PARAMETER IncludedEventTypes An array of event types to include.* .PARAMETER excludedEventTypes An array of event types to exclude.* .PARAMETER deviceMac Filter results by Mac Address .PARAMETER deviceName Filter results by device name. .PARAMETER deviceSerial Filter results by device serial number. .PARAMETER clientName Filter results bu client name. .PARAMETER clientIP Filter results by client IP. .PARAMETER clientMac Filter results by client MAC. .PARAMETER smDeviceName Filter device bu System Manager device name. .PARAMETER smDeviceMac Filter results by System Manager device MAC. .PARAMETER perPage Number of entries per page. 3-1000, default = 10. .PARAMETER startingAfter Date time to pull events after. .PARAMETER endingBefore Date time to pull events before. .PARAMETER first Pull the first page. .PARAMETER last Pull the last page. .PARAMETER prev Pull the previous page. .PARAMETER next Pull the next page. .OUTPUTS An array of Meraki event objects. .NOTES Event types supported by this network can by retrieved by using the Get-MerakiNetworkEventTypes function. .EXAMPLE Get content filtering network events for a network. PS> Get-MerakiNetworks |{$_.Name -like "Dallas"} | Get-MerakiNetworkEvents -includedEventTypes 'cf_block' -ProductType appliance .EXAMPLE Get network events for a specific client PS> Get-MerakiNetworkEvents -clientName 'DALJohnDoe' .EXAMPLE Paging: The maximum number of events you can retrieve per call is 1000. There are many events and 1000 events may only span a time period of a few minutes. To retrieve more events you can use subsequent function calls with the paging parameters. In the following command we retrieve the the content filtering events for the Dallas network for the month of June. PS> Get-MerakiNetworks |{$_.Name -like "Dallas"} | Get-MerakiNetworkEvents -includedEventTypes 'cf_block' -ProductType appliance -startingAfter "06/01/2020" -endingBefore "06/30/2020" -pageSize 50 .EXAMPLE This call will retrieve the first 50 events that meet the time span specified. There are significantly more events that meet this criteria. To retrieve the next page of events reissue the call and append the -next paging parameter. PS>Get-MerakiNetworks |{$_.Name -like "Dallas"} | Get-MerakiNetworkEvents -includedEventTypes 'cf_block' -ProductType appliance -startingAfter "06/01/2020" -endingBefore "06/30/2020" -pageSize 50 -next #> } Set-Alias -Name GMNetEvents -value Get-MerakiNetworkEvents -Option ReadOnly function Get-MerakiNetworkEventTypes() { [CmdletBinding()] Param( [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true )] [string]$id ) $Uri = "{0}/networks/{1}/events/eventTypes" -f $BaseURI, $id $Headers = Get-Headers try { $response = Invoke-RestMethod -Method GET -Uri $Uri -Headers $Headers -PreserveAuthorizationOnRedirect return $response } catch { throw $_ } <# .SYNOPSIS Returns all event types supported by this network. .PARAMETER id The network ID. .OUTPUTS An array of event type objects. #> } Set-Alias -Name GMNetET Get-MerakiNetworkEventTypes -Option ReadOnly function Get-MerakiNetworkClients () { [CmdletBinding(DefaultParameterSetName = 'default')] Param( [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true )] [Alias("NetworkId")] [string]$id, [ValidateScript({$_ -is [int]})] [ValidateRange(1,31)] [int]$Days, [ValidateScript({$_ -is [int]})] [int]$PerPage, [ValidateScript({$_ -is [int]})] [ValidateRange(0,1000)] [int]$Pages = 1, [ValidateSet("Offline","Online")] [string]$Statuses, [ValidateScript({$_ -match "^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})|([0-9a-fA-F]{4}\\.[0-9a-fA-F]{4}\\.[0-9a-fA-F]{4})$"})] [string]$Mac, [ValidateScript({$_ -match "\A(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\z"})] [string]$IP, [string]$PskGroup, [string]$OS, [string]$Description, [ValidateScript({$_ -is [int]})] [ValidateRange(1,4096)] [string]$VLAN, [string[]]$recentDeviceConnections, [Parameter(ParameterSetName = 'org')] [string]$OrgID, [Parameter(ParameterSetName = 'profile')] [string]$profileName ) Begin { If (-not $OrgID) { $config = Read-Config if ($profileName) { $OrgId = $config.profiles.$profileName if (-not $OrgID) { throw "Invalid profile name!" } } else { $OrgID = $config.profiles.default } } $Results = [List[PsObject]]::New() $Headers = Get-Headers Set-Variable -Name Query if ($StartDate) { $Query += "t0={0}" -f ($_startDate.ToString("O")) } if ($endDate) { if ($Query) {$Query += "&"} $Query = "{0}t1={1}" -f $Query, ($EndDate.ToString("O")) } if ($Days) { $Seconds = [TimeSpan]::FromDays($Days).TotalSeconds if ($Query) {$Query += "&"} $Query = "{0}timespan={1}" -f $Query, $Seconds } if ($Statuses) { if ($Query) {$Query += "&"} $Query = "{0}statuses={1}" -f $Query, $Statuses } if ($Mac) { if ($Query) {$Query += "&"} $Query = "{0}mac={1}" -f $Query, $Mac } if ($IP) { if ($Query) {$Query += "&"} $Query = "{0}ip={1}" -f $Query, $IP } if ($OS) { if ($Query) {$Query += "&"} $Query = "{0}os={1}" -f $Query, $OS } if ($Description) { if ($Query) {$Query += "&"} $Query = "{0}description={1}" -f $query, $Description } if ($VLAN) { if ($Query) {$Query += "&"} $Query = "{0}vlan={1}" -f $Query, $VLAN } if ($recentDeviceConnections) { if ($Query) {$Query += "&"} $Query = "{0}recentDeviceConnections={1}" -f $Query, $recentDeviceConnections } if ($PerPage) { if ($Query) {$Query += "&"} $Query = "{0}perPage={1}" -f $Query, $PerPage } } Process { $Uri = "{0}/networks/{1}/clients" -f $BaseURI, $Id if ($Query) { $Uri += "?{0}" -f $Query } try { #$response = Invoke-RestMethod -Method Get -Uri $Uri -Headers $Headers $response = Invoke-WebRequest -Method Get -Uri $Uri -Headers $Headers [List[PsObject]]$result = $response.Content | ConvertFrom-Json if ($result) { $Results.AddRange($result) } $page = 1 if ($Pages -ne 1) { $done = $false do { if ($response.RelationLink['next']) { $Uri = $response.RelationLink['next'] $response = Invoke-WebRequest -Method Get -Uri $Uri -Headers $Headers [List[PsObject]]$result = $response.Content | ConvertFrom-Json if ($result) { $Results.AddRange($result) } $page += 1 if ($page -gt $Pages) { $done = $true } } else { $done = $true } } until ($done) } } catch { Write-Host $id throw $_ } } End { $Results | ForEach-Object { if ($null -eq $_.description) { $_.description = $_.mac } $_ | Add-Member -MemberType NoteProperty -Name NetworkId -Value $id $_ | Add-Member -MemberType NoteProperty -Name ClientId -Value $_.id } return $Results.ToArray() } <# .SYNOPSIS Returns clients connections to the Network. .DESCRIPTION Returns a collection of client objects that are or have connected to the network withing the given time period. .PARAMETER id The network Id. .PARAMETER StartDate The starting date to retrieve client connections (Cannot be more than 31 days from today) .PARAMETER EndDate The ending date to retrieve client connections (cannot be more than 31 days from today) .PARAMETER Days Number of days back from today to retrieve client connections. If specified do not specify StartDate or EndDate (cannot be more than 31 days from today) .PARAMETER PerPage Sets the number of items returned per page. .PARAMETER Pages Sets the number of pages returned. Default is 1, 0 returns all pages. .PARAMETER Statuses Filters clients based on status. Can be one of 'Online' or 'Offline'. .PARAMETER Mac Filters clients based on a partial or full match for the mac address field. .PARAMETER IP Filters clients based on a partial or full match for the ip address field .PARAMETER OS Filters clients based on a partial or full match for the os (operating system) field. .PARAMETER Description Filters clients based on a partial or full match for the description field. .PARAMETER VLAN Filters clients based on the full match for the VLAN field. .PARAMETER recentDeviceConnections Filters clients based on recent connection type. Can be one of 'Wired' or 'Wireless'. .OUTPUTS A collection of client objects. #> } Set-Alias GMNetClients -Value Get-MerakiNetworkClients -Option ReadOnly function Get-MerakiNetworkClientApplicationUsage() { [CmdletBinding(DefaultParameterSetName = 'default')] Param( [Parameter( Mandatory = $true, ValueFromPipelineByPropertyName = $true )] [Alias('NetworkId')] [string]$Id, [Parameter( Mandatory, ValueFromPipelineByPropertyName)] [string]$ClientId, [string]$Clients, [ValidateScript({$_ -is [int]})] [ValidateRange(0,14)] [int]$SSIDNumber, [ValidateScript({$_ -is [DateTime]})] [Parameter(ParameterSetName = 'dates', Mandatory)] [Parameter(ParameterSetName = 'datesWithOrg', Mandatory)] [Parameter(ParameterSetName ='datesWithProfiles', Mandatory)] [DateTime]$StartDate, [ValidateScript({$_ -is [DateTime]})] [Parameter(ParameterSetName = 'dates', Mandatory)] [Parameter(ParameterSetName = 'datesWithOrg', Mandatory)] [Parameter(ParameterSetName ='datesWithProfiles', Mandatory)] [DateTime]$EndDate, [ValidateScript({$_ -is [int]})] [ValidateRange(1,31)] [Parameter(ParameterSetName = 'days', Mandatory)] [Parameter(ParameterSetName = 'daysWithOrg', Mandatory)] [Parameter(ParameterSetName = 'daysWithProfile', Mandatory)] [int]$Days, [ValidateScript({$_ -is [int]})] [ValidateSet(3,1000)] [int]$PerPage, [ValidateScript({$_ -is [int]})] [int]$Pages = 1, [Parameter(ParameterSetName = 'org', Mandatory)] [Parameter(ParameterSetName = 'datesWithOrg', Mandatory)] [Parameter(ParameterSetName = 'daysWithOrg', Mandatory)] [string]$OrgId, [Parameter(ParameterSetName = 'profile')] [Parameter(ParameterSetName = 'datesWithProfile')] [Parameter(ParameterSetName = 'daysWithProfile')] [string]$ProfileName ) Begin { If (-not $OrgID) { $config = Read-Config if ($profileName) { $OrgId = $config.profiles.$profileName if (-not $OrgID) { throw "Invalid profile name!" } } else { $OrgID = $config.profiles.default } } $Headers = Get-Headers if ($PerPage) { $Query = "perPage={0}" -f $perPage } if ($SSIDNumber) { if ($Query) {$Query += "&"} $Query = "{0}ssidNumber={1}" -f $Query, $SSIDNumber } if ($StartDate) { if ($Query) {$Query += "&"} $Query = "{0}t0={1}" -f $Query, ($startDate.ToString("O")) } if ($EndDate) { if ($Query) {$Query += "&"} $Query = "{0}t1={1}" -f $Query, ($EndDate.ToString("O")) } if ($Days) { $Seconds = [timespan]::FromDays($Days).TotalSeconds if ($Query) {$Query += "&"} $Query = "{0}timespan={1}" -f $Query, $Seconds } if ($PerPage) { if ($Query) {$Query += "&"} $Query = "{0}perPage={1}" -f $Query, $PerPage } $Results = [List[PsObject]]::New() } Process { $Uri = "{0}/networks/{1}/clients/applicationUsage" -f $BaseURI, $Id if ($Query) { $Uri = "{1}?{1}" -f $Uri, $Query } try { $response = Invoke-WebRequest -Method GET -Uri $Uri -Headers $Headers -PreserveAuthorizationOnRedirect [List[PsObject]]$result = $response.Content | ConvertFrom-Json if ($result) { $Result.AddRange($result) } $Pages if ($Pages -ne 1) { $done = $false do { if ($response.RelationLink['next']) { $Uri = $response.RelationLink['next'] $response = Invoke-WebRequest -Method Get -Uri $Uri -Header $Headers -PreserveAuthorizationOnRedirect [List[PsObject]]$result = $response.Content | ConvertFrom-Json if ($result) { $Results.Add($result) } $page += 1 if ($page -gt $Pages) { $done = $true } } else { $done = $true } } until ($done) } return $Results.ToArray() } catch { throw $_ } } <# .SYNOPSIS Return the application usage data for clients. .DESCRIPTION Return the application usage data for clients. Usage data is in kilobytes. Clients can be identified by client keys or either the MACs or IPs depending on whether the network uses Track-by-IP. .PARAMETER Id The Network Id. .PARAMETER Clients A array of client keys, MACs or IPs. .PARAMETER SSIDNumber An SSID number to include. If not specified, usage histories application usage for all SSIDs will be returned. .PARAMETER StartDate The starting date to retrieve date (Cannot be more than 31 days before today). .PARAMETER EndDate The ending date to retrieve data (Cannot be more than 31 days after today). .PARAMETER Days Number of days before to day to retrieve date. (Cannot be more than 31 days before today). Default is 1 day. .PARAMETER PerPage The number of entries per page returned. Acceptable range is 3 - 1000. .OUTPUTS An array of application usage statistics. #> } Set-Alias -Name GMNetClientAppUsage -Value Get-MerakiNetworkClientApplicationUsage -Option ReadOnly function Get-MerakiNetworkClientBandwidthUsage() { [CmdletBinding(DefaultParameterSetName = 'default')] Param( [Parameter( Mandatory = $true, ValueFromPipelineByPropertyName = $true )] [Alias('NetworkId')] [string]$id, [ValidateScript({$_ -is [DateTime]})] [Alias('StartTime')] [Parameter(ParameterSetName = 'dates', Mandatory)] [Parameter(ParameterSetName = 'datesWithOrg', Mandatory)] [Parameter(ParameterSetName ='datesWithProfiles', Mandatory)] [datetime]$StartDate, [ValidateScript({$_ -is [DateTime]})] [Alias('EndTime')] [Parameter(ParameterSetName = 'dates', Mandatory)] [Parameter(ParameterSetName = 'datesWithOrg', Mandatory)] [Parameter(ParameterSetName ='datesWithProfiles', Mandatory)] [datetime]$EndDate, [ValidateScript({$_ -is [int]})] [ValidateRange(1,31)] [Parameter(ParameterSetName = 'days', Mandatory)] [Parameter(ParameterSetName = 'daysWithOrg', Mandatory)] [Parameter(ParameterSetName = 'daysWithProfile', Mandatory)] [int]$Days, [ValidateScript({$_ -is [int]})] [ValidateRange(3,1000)] [int]$perPage, [ValidateScript({$_ -is [int]})] [Int]$Pages, [Parameter(ParameterSetName = 'org', Mandatory)] [Parameter(ParameterSetName = 'datesWithOrg', Mandatory)] [Parameter(ParameterSetName = 'daysWithOrg', Mandatory)] [string]$OrgId, [Parameter(ParameterSetName = 'profile')] [Parameter(ParameterSetName = 'datesWithProfile')] [Parameter(ParameterSetName = 'daysWithProfile')] [string]$ProfileName ) Begin { If (-not $OrgID) { $config = Read-Config if ($profileName) { $OrgId = $config.profiles.$profileName if (-not $OrgID) { throw "Invalid profile name!" } } else { $OrgID = $config.profiles.default } } $Headers = Get-Headers Set-Variable -Name Query if ($StartDate) { $Query = "t0={0}" -f ($StartDate.ToString("O")) } if ($EndDate) { if ($Query) {$Query += "&"} $Query = "{0}t1={1}" -f $Query, ($EndDate.ToString("O")) } if ($Days) { if ($Query) {$Query += "&"} $Seconds = [TimeSpan]::FromDays($Days).TotalSeconds $Query = "{0}timespan={1}" -f $Query, $Seconds } if ($perPage) { if ($Query) {$Query += "&"} $Query = "{0}perPage={1}" -f $Query, $perPage } $Results = [List[PsObject]]::New() } Process { $Uri = "{0}/networks/{1}/clients/bandwidthUsageHistory" -f $BaseURI, $Id if ($Query) { $Uri = "{0}?{1}" -f $Uri, $Query } try { $response = Invoke-WebRequest -Method GET -Uri $Uri -Headers $Headers -PreserveAuthorizationOnRedirect [List[PsObject]]$result = $response.Content | ConvertFrom-Json if ($result) { $Results.AddRange($result) } $page = 1 if ($Pages -ne 1) { $done = $false do { if ($response.RelationLink['next']) { $Uri = $response.RelationLink['next'] $response = Invoke-WebRequest -Method Get -Uri $Uri -Headers $Headers -PreserveAuthorizationOnRedirect [List[PsObject]]$result = $response.Content | ConvertFrom-Json if ($result) { $Results.AddRange($result) } $page += 1 if ($page -gt $Pages) { $done = $true } } else { $done = $true } } until ($done) } return $Results.ToArray() } catch { throw $_ } } <# .SYNOPSIS Returns traffic consumption rates for all clients. .DESCRIPTION Returns a time series of total traffic consumption rates for all clients on a network within a given timespan, in megabits per second. .PARAMETER id Network Id .PARAMETER StartTime The beginning of the timespan for the data. Must be no more than 31 days from today. .PARAMETER EndTime The end time for the data. Must be no more than 31 days after StartTime. .PARAMETER Days Number fo days prior to today to return data. .PARAMETER perPage The number of entries per page returned. Acceptable range is 3 - 1000. Default is 1000. .OUTPUTS Am array of usage statistics. #> } Set-Alias -Name GMNetCltBWUsage -Value Get-MerakiNetworkClientBandwidthUsage -Option ReadOnly function Get-MerakiNetworkTraffic() { [CmdletBinding()] Param( [Parameter( Mandatory, ValueFromPipelineByPropertyName )] [Alias('NetworkId')] [string]$Id, [ValidateScript({$_ -is [DateTime]})] [Alias('StartTime')] [Parameter(ParameterSetName = 'dates', Mandatory)] [Parameter(ParameterSetName = 'datesWithOrg', Mandatory)] [Parameter(ParameterSetName ='datesWithProfiles', Mandatory)] [datetime]$StartDate, [ValidateScript({$_ -is [int]})] [ValidateRange(1,31)] [Parameter(ParameterSetName = 'days', Mandatory)] [Parameter(ParameterSetName = 'daysWithOrg', Mandatory)] [Parameter(ParameterSetName = 'daysWithProfile', Mandatory)] [int]$Days, [ValidateSet('combined', 'wireless', 'switch', 'appliance')] [string]$DeviceType = 'combined' ) Begin { if ($Days) { $Seconds = [TimeSpan]::FromDays($Days).TotalSeconds $Query = "timespan={0}" -f $Seconds } if ($StartDate) { if ($Query) {$Query += '&'} $Query = "{0}t0={1}" -f $Query, ($StartDate.ToString("O")) } } Process { $Uri = "{0}/networks/{1}/traffic" -f $BaseURI, $Id if ($Query) { $Uri = "{0}?{1}" -f $Uri, $Query } try { $response = Invoke-RestMethod -Method Get -Uri $Uri -Headers $Headers -PreserveAuthorizationOnRedirect return $response } catch { throw $_ } } } |