diff --git a/TeamsE911Automation/build/build.ps1 b/TeamsE911Automation/build/build.ps1 index fd97cb4..6193805 100644 --- a/TeamsE911Automation/build/build.ps1 +++ b/TeamsE911Automation/build/build.ps1 @@ -164,10 +164,10 @@ foreach ( $p in $Parameters ) { # Remove old release, copy all data from src to releasePath if ( -not ( Test-Path -Path $releasePath -PathType Container) ) { - New-Item -Path $releasePath -ItemType Directory | Out-Null + $null = New-Item -Path $releasePath -ItemType Directory } -Get-ChildItem "${releasePath}/" -Recurse | Remove-Item -Recurse | Out-Null +$null = Get-ChildItem "${releasePath}/" -Recurse | Remove-Item -Recurse $srcPathPattern = [Regex]::Escape($srcPath) foreach ($srcFile in @($Public + $Private)) { @@ -176,7 +176,7 @@ foreach ($srcFile in @($Public + $Private)) { $targetFile = $srcFile.FullName -Replace $srcPathPattern, $releasePath $targetFolder = $srcFile.Directory.FullName -Replace $srcPathPattern, $releasePath if (!(Test-Path -Path $targetFolder)) { - New-Item -Path $targetFolder -ItemType Directory | Out-Null + $null = New-Item -Path $targetFolder -ItemType Directory } if ((Test-Path -Path $targetFile)) { Remove-Item -Path $targetFile -Force -ErrorAction SilentlyContinue @@ -227,12 +227,12 @@ foreach ($ClassFile in $ClassFiles) { foreach ($line in $currClass) { [void]$Classes.AppendLine($line) } + [void]$Classes.AppendLine() } if ($Classes.Length -gt 0) { Add-Content -Path $moduleFile -Value '# Loading Classes' Add-Content -Path $moduleFile -Value '' Add-Content -Path $moduleFile -Value $Classes.ToString() - Add-Content -Path $moduleFile -Value '' } #Get public and private function definition files. @@ -249,7 +249,7 @@ foreach ($import in @($Private + $Public)) { Add-Content -Path $moduleFile -Value "# $($import.BaseName)" $Raw = Get-Content -Path $import.FullName -Raw $Raw = ($Raw.Trim() -replace '(\r?\n){3,}',([Environment]::NewLine + [Environment]::NewLine)) + [Environment]::NewLine - $Raw | Add-Content -Path $moduleFile | Out-Null + $null = $Raw | Add-Content -Path $moduleFile } catch { Write-Error -Message "Failed to import function $($import.FullName): $_" diff --git a/TeamsE911Automation/src/TeamsE911Automation.psd1 b/TeamsE911Automation/src/TeamsE911Automation.psd1 index 00a81e3..acae817 100644 --- a/TeamsE911Automation/src/TeamsE911Automation.psd1 +++ b/TeamsE911Automation/src/TeamsE911Automation.psd1 @@ -3,7 +3,7 @@ # # Generated by: Andy Thompson (andthom) # -# Generated on: 5/22/2022 +# Generated on: 5/24/2022 # @{ @@ -11,7 +11,7 @@ RootModule = 'TeamsE911Automation.psm1' # Version number of this module. - ModuleVersion = '0.2.22142.1' + ModuleVersion = '0.2.22144.1' # Supported PSEditions CompatiblePSEditions = 'Desktop', 'Core' diff --git a/TeamsE911Automation/src/TeamsE911Automation.psm1 b/TeamsE911Automation/src/TeamsE911Automation.psm1 index 9fc9832..0113ef2 100644 --- a/TeamsE911Automation/src/TeamsE911Automation.psm1 +++ b/TeamsE911Automation/src/TeamsE911Automation.psm1 @@ -1386,7 +1386,7 @@ class E911ModuleState { $dup = $false if ([E911ModuleState]::NetworkObjects.ContainsKey($Hash)) { $Test = [E911ModuleState]::NetworkObjects[$Hash] - if ([E911Location]::Equals($obj, $Test.Location)) { + if ([E911Location]::Equals($obj, $Test._location)) { return $Test } $dup = $true @@ -1785,7 +1785,7 @@ class E911NetworkObject { else { $LocationId = '"{0}"' -f $this._location.Id.ToString() } - [void]$sb.AppendFormat('Set-CsOnlineLis{0} -LocationId {1}', $this.Type, $LocationId) + [void]$sb.AppendFormat('$null = Set-CsOnlineLis{0} -LocationId {1}', $this.Type, $LocationId) if (![string]::IsNullOrEmpty($this.Description)) { [void]$sb.AppendFormat(' -Description "{0}"', $this.Description) } @@ -1801,7 +1801,7 @@ class E911NetworkObject { if ($this.Type -eq [NetworkObjectType]::WirelessAccessPoint) { [void]$sb.AppendFormat(' -Bssid "{0}"', $this.Identifier.PhysicalAddress) } - [void]$sb.Append(' -ErrorAction Stop | Out-Null') + [void]$sb.Append(' -ErrorAction Stop') $this._command = $sb.ToString() } return $this._command @@ -1881,8 +1881,59 @@ class E911NetworkObject { $Desc2 = if ($null -eq $Value2.LocationId -and $Value2 -isnot [E911NetworkObject]) { $Value2.NetworkDescription } else { $Value2.Description } $D1 = if ([string]::IsNullOrEmpty($Desc1)) { '' } else { $Desc1 } $D2 = if ([string]::IsNullOrEmpty($Desc2)) { '' } else { $Desc2 } + if ($D1 -ne $D2) { + return $false + } + # see if locations are the same + # if Value1 is row + $LocationsEqual = if ($null -eq $Value1.LocationId -and $Value1 -isnot [E911NetworkObject]) { + # if Value2 is row + if ($null -eq $Value2.LocationId -and $Value2 -isnot [E911NetworkObject]) { + [E911Location]::Equals($Value1, $Value2) + } + # if Value2 is network object + elseif ($Value2 -is [E911NetworkObject]) { + [E911Location]::Equals($Value1, $Value2._location) + } + # if Value2 is online + else { + # cannot compare online network object to row on anything other than hash... or should we see if the online location exists (that would be expensive) + throw "(Value2 is online) cannot compare online network object to row network object effectively" + } + } + # if Value1 is network object + elseif ($Value1 -is [E911NetworkObject]) { + # if Value2 is row + if ($null -eq $Value2.LocationId -and $Value2 -isnot [E911NetworkObject]) { + [E911Location]::Equals($Value1._location, $Value2) + } + # if Value2 is network object + elseif ($Value2 -is [E911NetworkObject]) { + $Value1._location.Equals($Value2._location) + } + # if Value2 is online + else { + $Value1.Id.ToString() -eq $Value2.LocationId + } + } + # if Value1 is online + else { + # if Value2 is row + if ($null -eq $Value2.LocationId -and $Value2 -isnot [E911NetworkObject]) { + # cannot compare online network object to row on anything other than hash... or should we see if the online location exists (that would be expensive) + throw "(Value2 is row) cannot compare online network object to row network object effectively" + } + # if Value2 is network object + elseif ($Value2 -is [E911NetworkObject]) { + $Value1.LocationId -eq $Value2.Id.ToString() + } + # if Value2 is online + else { + $Value1.LocationId -eq $Value2.LocationId + } + } - return $D1 -eq $D2 + return $LocationsEqual } [bool] Equals($Value) { @@ -2431,7 +2482,7 @@ function Get-CsE911OnlineConfiguration { # (imported from .\public\Set-CsE911OnlineChange.ps1) function Set-CsE911OnlineChange { - [CmdletBinding(DefaultParameterSetName = 'Execute')] + [CmdletBinding(DefaultParameterSetName = 'Execute', SupportsShouldProcess = $true, ConfirmImpact = 'Medium')] param ( # Parameter help description [Parameter(Mandatory = $true, ValueFromPipeline = $true, ParameterSetName = 'Execute')] @@ -2541,7 +2592,9 @@ function Set-CsE911OnlineChange { try { Write-Verbose "[$($vsw.Elapsed.TotalSeconds.ToString('F3'))] [$($MyInvocation.MyCommand.Name)] $($Change.ProcessInfo)" if (!$ValidateOnly) { - Invoke-Command -ScriptBlock $Change.ProcessInfo -NoNewScope -ErrorAction Stop | Out-Null + if ($PSCmdlet.ShouldProcess()) { + $null = Invoke-Command -ScriptBlock $Change.ProcessInfo -NoNewScope -ErrorAction Stop + } } if (![string]::IsNullOrEmpty($ExecutionPlanPath)) { $Change.ProcessInfo.ToString() | Add-Content -Path $ExecutionPlanPath @@ -2621,7 +2674,9 @@ function Set-CsE911OnlineChange { try { Write-Verbose "[$($vsw.Elapsed.TotalSeconds.ToString('F3'))] [$($MyInvocation.MyCommand.Name)] $($Change.ProcessInfo)" if (!$ValidateOnly) { - Invoke-Command -ScriptBlock $Change.ProcessInfo -NoNewScope -ErrorAction Stop | Out-Null + if ($PSCmdlet.ShouldProcess()) { + $null = Invoke-Command -ScriptBlock $Change.ProcessInfo -NoNewScope -ErrorAction Stop + } } if (![string]::IsNullOrEmpty($ExecutionPlanPath)) { $Change.ProcessInfo.ToString() | Add-Content -Path $ExecutionPlanPath @@ -2647,10 +2702,12 @@ function Set-CsE911OnlineChange { # (imported from .\private\Reset-CsE911Cache.ps1) function Reset-CsE911Cache { - [CmdletBinding()] + [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Low')] param() end { - [E911ModuleState]::FlushCaches($null) + if ($PSCmdlet.ShouldProcess()) { + [E911ModuleState]::FlushCaches($null) + } } } diff --git a/TeamsE911Automation/src/classes/E911ModuleState.ps1 b/TeamsE911Automation/src/classes/E911ModuleState.ps1 index 456f763..1cce637 100644 --- a/TeamsE911Automation/src/classes/E911ModuleState.ps1 +++ b/TeamsE911Automation/src/classes/E911ModuleState.ps1 @@ -340,7 +340,7 @@ class E911ModuleState { $dup = $false if ([E911ModuleState]::NetworkObjects.ContainsKey($Hash)) { $Test = [E911ModuleState]::NetworkObjects[$Hash] - if ([E911Location]::Equals($obj, $Test.Location)) { + if ([E911Location]::Equals($obj, $Test._location)) { return $Test } $dup = $true diff --git a/TeamsE911Automation/src/classes/E911NetworkObject.ps1 b/TeamsE911Automation/src/classes/E911NetworkObject.ps1 index 34409d7..2f8dfc7 100644 --- a/TeamsE911Automation/src/classes/E911NetworkObject.ps1 +++ b/TeamsE911Automation/src/classes/E911NetworkObject.ps1 @@ -129,7 +129,7 @@ class E911NetworkObject { else { $LocationId = '"{0}"' -f $this._location.Id.ToString() } - [void]$sb.AppendFormat('Set-CsOnlineLis{0} -LocationId {1}', $this.Type, $LocationId) + [void]$sb.AppendFormat('$null = Set-CsOnlineLis{0} -LocationId {1}', $this.Type, $LocationId) if (![string]::IsNullOrEmpty($this.Description)) { [void]$sb.AppendFormat(' -Description "{0}"', $this.Description) } @@ -145,7 +145,7 @@ class E911NetworkObject { if ($this.Type -eq [NetworkObjectType]::WirelessAccessPoint) { [void]$sb.AppendFormat(' -Bssid "{0}"', $this.Identifier.PhysicalAddress) } - [void]$sb.Append(' -ErrorAction Stop | Out-Null') + [void]$sb.Append(' -ErrorAction Stop') $this._command = $sb.ToString() } return $this._command @@ -225,8 +225,59 @@ class E911NetworkObject { $Desc2 = if ($null -eq $Value2.LocationId -and $Value2 -isnot [E911NetworkObject]) { $Value2.NetworkDescription } else { $Value2.Description } $D1 = if ([string]::IsNullOrEmpty($Desc1)) { '' } else { $Desc1 } $D2 = if ([string]::IsNullOrEmpty($Desc2)) { '' } else { $Desc2 } + if ($D1 -ne $D2) { + return $false + } + # see if locations are the same + # if Value1 is row + $LocationsEqual = if ($null -eq $Value1.LocationId -and $Value1 -isnot [E911NetworkObject]) { + # if Value2 is row + if ($null -eq $Value2.LocationId -and $Value2 -isnot [E911NetworkObject]) { + [E911Location]::Equals($Value1, $Value2) + } + # if Value2 is network object + elseif ($Value2 -is [E911NetworkObject]) { + [E911Location]::Equals($Value1, $Value2._location) + } + # if Value2 is online + else { + # cannot compare online network object to row on anything other than hash... or should we see if the online location exists (that would be expensive) + throw "(Value2 is online) cannot compare online network object to row network object effectively" + } + } + # if Value1 is network object + elseif ($Value1 -is [E911NetworkObject]) { + # if Value2 is row + if ($null -eq $Value2.LocationId -and $Value2 -isnot [E911NetworkObject]) { + [E911Location]::Equals($Value1._location, $Value2) + } + # if Value2 is network object + elseif ($Value2 -is [E911NetworkObject]) { + $Value1._location.Equals($Value2._location) + } + # if Value2 is online + else { + $Value1.Id.ToString() -eq $Value2.LocationId + } + } + # if Value1 is online + else { + # if Value2 is row + if ($null -eq $Value2.LocationId -and $Value2 -isnot [E911NetworkObject]) { + # cannot compare online network object to row on anything other than hash... or should we see if the online location exists (that would be expensive) + throw "(Value2 is row) cannot compare online network object to row network object effectively" + } + # if Value2 is network object + elseif ($Value2 -is [E911NetworkObject]) { + $Value1.LocationId -eq $Value2.Id.ToString() + } + # if Value2 is online + else { + $Value1.LocationId -eq $Value2.LocationId + } + } - return $D1 -eq $D2 + return $LocationsEqual } [bool] Equals($Value) { diff --git a/TeamsE911Automation/src/private/Reset-CsE911Cache.ps1 b/TeamsE911Automation/src/private/Reset-CsE911Cache.ps1 index 215cdc5..16b304a 100644 --- a/TeamsE911Automation/src/private/Reset-CsE911Cache.ps1 +++ b/TeamsE911Automation/src/private/Reset-CsE911Cache.ps1 @@ -1,7 +1,9 @@ function Reset-CsE911Cache { - [CmdletBinding()] + [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Low')] param() end { - [E911ModuleState]::FlushCaches($null) + if ($PSCmdlet.ShouldProcess()) { + [E911ModuleState]::FlushCaches($null) + } } } diff --git a/TeamsE911Automation/src/public/Set-CsE911OnlineChange.ps1 b/TeamsE911Automation/src/public/Set-CsE911OnlineChange.ps1 index 8dc3a5b..3c48d70 100644 --- a/TeamsE911Automation/src/public/Set-CsE911OnlineChange.ps1 +++ b/TeamsE911Automation/src/public/Set-CsE911OnlineChange.ps1 @@ -1,5 +1,5 @@ function Set-CsE911OnlineChange { - [CmdletBinding(DefaultParameterSetName = 'Execute')] + [CmdletBinding(DefaultParameterSetName = 'Execute', SupportsShouldProcess = $true, ConfirmImpact = 'Medium')] param ( # Parameter help description [Parameter(Mandatory = $true, ValueFromPipeline = $true, ParameterSetName = 'Execute')] @@ -109,7 +109,9 @@ function Set-CsE911OnlineChange { try { Write-Verbose "[$($vsw.Elapsed.TotalSeconds.ToString('F3'))] [$($MyInvocation.MyCommand.Name)] $($Change.ProcessInfo)" if (!$ValidateOnly) { - Invoke-Command -ScriptBlock $Change.ProcessInfo -NoNewScope -ErrorAction Stop | Out-Null + if ($PSCmdlet.ShouldProcess()) { + $null = Invoke-Command -ScriptBlock $Change.ProcessInfo -NoNewScope -ErrorAction Stop + } } if (![string]::IsNullOrEmpty($ExecutionPlanPath)) { $Change.ProcessInfo.ToString() | Add-Content -Path $ExecutionPlanPath @@ -189,7 +191,9 @@ function Set-CsE911OnlineChange { try { Write-Verbose "[$($vsw.Elapsed.TotalSeconds.ToString('F3'))] [$($MyInvocation.MyCommand.Name)] $($Change.ProcessInfo)" if (!$ValidateOnly) { - Invoke-Command -ScriptBlock $Change.ProcessInfo -NoNewScope -ErrorAction Stop | Out-Null + if ($PSCmdlet.ShouldProcess()) { + $null = Invoke-Command -ScriptBlock $Change.ProcessInfo -NoNewScope -ErrorAction Stop + } } if (![string]::IsNullOrEmpty($ExecutionPlanPath)) { $Change.ProcessInfo.ToString() | Add-Content -Path $ExecutionPlanPath @@ -212,3 +216,4 @@ function Set-CsE911OnlineChange { Write-Verbose "[$($vsw.Elapsed.TotalSeconds.ToString('F3'))] [$($MyInvocation.MyCommand.Name)] Finished" } } + diff --git a/scripts/BulkUploadFunction.ps1 b/scripts/BulkUploadFunction.ps1 index 7f7b820..eac9da0 100644 --- a/scripts/BulkUploadFunction.ps1 +++ b/scripts/BulkUploadFunction.ps1 @@ -131,10 +131,10 @@ try {{ }} catch {{ $Connected = $false - Import-Module -Name MicrosoftTeams -ErrorAction Stop | Out-Null + $null = Import-Module -Name MicrosoftTeams -ErrorAction Stop }} if (!$Connected) {{ - Connect-MicrosoftTeams -AccessTokens ($_sync.TokenCache.Values.AccessToken) -ErrorAction Stop | Out-Null + $null = Connect-MicrosoftTeams -AccessTokens ($_sync.TokenCache.Values.AccessToken) -ErrorAction Stop [Microsoft.TeamsCmdlets.PowerShell.Connect.TokenProvider.AccessTokenCache]::AccessTokens = $_sync.TokenCache [Microsoft.TeamsCmdlets.Powershell.Connect.TeamsPowerShellSession]::SessionProvider.PublicClientApplication = $_sync.Application }} @@ -217,9 +217,9 @@ finally {{ $Runspace = $Runspaces.Where({ $_.RunspaceAvailability -eq 'Available' }, 'First', 1)[0] } $newJob.PowerShell.Runspace = $Runspace - $newJob.PowerShell.AddScript(($BaseScript -f $Batches[$i].Script)) | Out-Null + $null = $newJob.PowerShell.AddScript(($BaseScript -f $Batches[$i].Script)) $newJob.Handle = $newJob.PowerShell.BeginInvoke() - $Jobs.Add($newJob) | Out-Null + $null = $Jobs.Add($newJob) } do { if (([DateTime]::Now - $curr).TotalSeconds -ge $UpdateInterval) { diff --git a/scripts/runtest.ps1 b/scripts/runtest.ps1 index b01e9a6..2465393 100644 --- a/scripts/runtest.ps1 +++ b/scripts/runtest.ps1 @@ -24,7 +24,7 @@ function Remove-CsE911Configuration { $i = 0 foreach ($Subnet in $Subnets) { Write-Verbose "Removing Subnet:$($Subnet.Subnet)" - Remove-CsOnlineLisSubnet -Subnet $Subnet.Subnet | Out-Null + $null = Remove-CsOnlineLisSubnet -Subnet $Subnet.Subnet $i++ } Write-Information "Removed $i subnets" @@ -33,7 +33,7 @@ function Remove-CsE911Configuration { $i = 0 foreach ($Switch in $Switches) { Write-Verbose "Removing Switch:$($Switch.ChassisId)" - Remove-CsOnlineLisSwitch -ChassisId $Switch.ChassisId | Out-Null + $null = Remove-CsOnlineLisSwitch -ChassisId $Switch.ChassisId $i++ } Write-Information "Removed $i switches" @@ -42,7 +42,7 @@ function Remove-CsE911Configuration { $i = 0 foreach ($Port in $Ports) { Write-Verbose "Removing Port:$($Port.ChassisId):$($Port.PortId)" - Remove-CsOnlineLisPort -PortId $Port.PortId -ChassisId $Port.ChassisId | Out-Null + $null = Remove-CsOnlineLisPort -PortId $Port.PortId -ChassisId $Port.ChassisId $i++ } Write-Information "Removed $i ports" @@ -51,7 +51,7 @@ function Remove-CsE911Configuration { $i = 0 foreach ($WAP in $WirelessAccessPoints) { Write-Verbose "Removing WAP:$($WAP.Bssid)" - Remove-CsOnlineLisWirelessAccessPoint -Bssid $WAP.Bssid | Out-Null + $null = Remove-CsOnlineLisWirelessAccessPoint -Bssid $WAP.Bssid $i++ } Write-Information "Removed $i wireless access points" @@ -64,13 +64,13 @@ function Remove-CsE911Configuration { $addr = $Addresses.Where({ $_.CivicAddressId -eq $Location.CivicAddressId -and $Location.LocationId -ne $_.DefaultLocationId }) if ($null -eq $addr -or $addr.Count -eq 0) { continue } Write-Verbose "Removing Location:$($Location.LocationId)-$($Location.Location)" - Remove-CsOnlineLisLocation -LocationId $Location.LocationId | Out-Null + $null = Remove-CsOnlineLisLocation -LocationId $Location.LocationId $i++ } foreach ($Address in $Addresses) { if ($Address.NumberOfVoiceUsers -gt 0 -or $Address.NumberOfTelephoneNumbers -gt 0 ) { continue } Write-Verbose "Removing Address:$($Address.CivicAddressId)-$($Address.HouseNumber) $($Address.StreetName)" - Remove-CsOnlineLisCivicAddress -CivicAddressId $Address.CivicAddressId | Out-Null + $null = Remove-CsOnlineLisCivicAddress -CivicAddressId $Address.CivicAddressId $j++ } Write-Information "Removed $i locations" @@ -105,7 +105,7 @@ function Write-TestEnd { $ConfigApiCmdlets = [Microsoft.Teams.ConfigApi.Cmdlets.SessionStateStore]::TryConfigApiSessionInfo.SessionConfiguration.RemotingCmdletsFlightedForAutoRest $ExistingConfiguration = [Collections.Generic.List[string]]::new() -$ExistingConfiguration.AddRange($ConfigApiCmdlets) | Out-Null +$null = $ExistingConfiguration.AddRange($ConfigApiCmdlets) $CmdletsToCheck = Get-Command -Verb @('Get', 'Set', 'Remove') -Noun CsOnlineLis* | Select-Object -ExpandProperty Name $changedFlighting = $false Write-Separator @@ -115,14 +115,14 @@ foreach ($cmdlet in $CmdletsToCheck) { if ($cmdlet -in $ConfigApiCmdlets) { Write-Information "REST: $cmdlet" if ($Endpoint -eq "Legacy") { - $ConfigApiCmdlets.Remove($cmdlet) | Out-Null + $null = $ConfigApiCmdlets.Remove($cmdlet) $changedFlighting = $true } } else { Write-Information "Legacy: $cmdlet" if ($Endpoint -eq "REST") { - $ConfigApiCmdlets.Add($cmdlet) | Out-Null + $null = $ConfigApiCmdlets.Add($cmdlet) $changedFlighting = $true } } @@ -191,18 +191,18 @@ finally { $ConfigApiCmdlets = [Microsoft.Teams.ConfigApi.Cmdlets.SessionStateStore]::TryConfigApiSessionInfo.SessionConfiguration.RemotingCmdletsFlightedForAutoRest foreach ($prev in $ExistingConfiguration) { if ($prev -notin $ConfigApiCmdlets) { - $ConfigApiCmdlets.Add($prev) | Out-Null + $null = $ConfigApiCmdlets.Add($prev) } } $Added = [Collections.Generic.List[string]]::new() foreach ($curr in $ConfigApiCmdlets) { if ($curr -notin $ExistingConfiguration) { - $Added.Add($curr) | Out-Null + $null = $Added.Add($curr) } } foreach ($curr in $Added) { if ($curr -notin $ExistingConfiguration) { - $ConfigApiCmdlets.Remove($curr) | Out-Null + $null = $ConfigApiCmdlets.Remove($curr) } } Write-Separator