Public/Get-RpTicketBlock.ps1
function Get-RpTicketBlock { <# .SYNOPSIS Retrieves hardware and stream information for a list of camera configuration items. .DESCRIPTION This function processes a list of camera configuration items, retrieves relevant hardware information such as the recording server, hardware name, stream name, serial number, model, IP address, MAC address, username, and password. The data is grouped into an array of PSCustomObjects representing each camera's hardware details. Optionally, the information can be displayed in a WPF window and/or returned as objects to the pipeline. .COMPONENT CustomVMSCmdlets .PARAMETER Cameras A list of camera configuration items (VideoOS.Platform.ConfigurationItems.Camera) from which the hardware information will be retrieved. This parameter is mandatory and accepts input from the pipeline. .PARAMETER ShowWindow If specified, a WPF window will display the grouped camera hardware information in a formatted list. The window allows users to click on an item to copy its details. .PARAMETER ReturnObjects If specified, the function returns the grouped camera hardware information as PSCustomObject items to the pipeline. .EXAMPLE Get-RpTicketBlock -Cameras $cameraList -showWindow Retrieves camera hardware information from the specified camera configuration items and displays it in a WPF window. .EXAMPLE $cameraInfo = Get-RpTicketBlock -Cameras $cameraList -ReturnObjects Retrieves camera hardware information from the specified camera configuration items and returns the results as objects to the pipeline. .EXAMPLE $cameraList | Get-RpTicketBlock -showWindow Pipes a list of camera configuration items and displays the retrieved hardware information in a WPF window. .LINK https://www.remotepro.dev/en-US/Get-RpTicketBlock #> [CmdletBinding(DefaultParameterSetName = 'CameraConfigurationItems')] param ( [Parameter(ParameterSetName = 'CameraConfigurationItems', Mandatory = $true, ValueFromPipeline = $true)] [System.Collections.Generic.List[VideoOS.Platform.ConfigurationItems.Camera]]$Cameras, [Parameter(ParameterSetName = 'CameraConfigurationItems')] [Switch]$ShowWindow, [Parameter(ParameterSetName = 'CameraConfigurationItems')] [Switch]$ReturnObjects ) begin { $connectionValid = $true if ($CheckConnection) { if (-not (Test-RpVmsConnection -ShowErrorDialog $true)) { $connectionValid = $false } } } process { if (-not $connectionValid) { Write-Host "Connection validation failed. No VMS connection available." return } $groupedCameras = @() foreach($cam in $Cameras){ $hwConfigItem = Get-ConfigurationItem -Path $cam.ParentItemPath $hwProperties = $hwConfigItem.Properties $hw = Get-VmsHardware -Id $hwProperties.value[0] $hwSettings = $hw | Get-HardwareSetting $hwPw = $hw | Get-VmsHardwarePassword $url = $hw.Address $CleanedIPAddress = $url -replace '^http://|/$', '' $inputString = $hwConfigItem.ParentPath $bracketPattern = '\[(.*?)\]' $match = [regex]::Match($inputString, $bracketPattern) $recorderGUID = $match.Groups[1].Value $recordingServer = Get-VmsRecordingServer -Id $recorderGUID $recordingServerModified = "$($recordingServer.DisplayName) @ $($recordingServer.ServerID.Uri)" $SelectedCamHw = [PSCustomObject]@{ RecordingServer = $recordingServerModified HardwareName = $hw.DisplayName StreamName = $cam.Name Serial = $hwSettings.SerialNumber Model = $hw.Model Address = $CleanedIPAddress MacAddress = $hwSettings.MacAddress Username = $hw.Username Password = $hwPw } $groupedCameras += $SelectedCamHw } if ($showWindow) { Add-Type -AssemblyName PresentationFramework Add-Type -AssemblyName PresentationCore $xaml = @" <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:mdControls="clr-namespace:MaterialDesignThemes.Wpf;assembly=MaterialDesignThemes.Wpf" Title="Camera Hardware Information" WindowStartupLocation="CenterScreen" SizeToContent="Width" MinWidth="800" MinHeight="400" MaxHeight="600" Background="{DynamicResource MaterialDesignPaper}"> <Window.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <materialDesign:BundledTheme x:Key="AppTheme" BaseTheme="Light" PrimaryColor="Grey" SecondaryColor="Lime" /> <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesign2.Defaults.xaml" /> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Window.Resources> <Grid Margin="10"> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <!-- Instruction Label --> <TextBlock Grid.Row="0" Text="Click on an item to copy its details" FontSize="14" FontWeight="Bold" Foreground="{DynamicResource PrimaryHueMidBrush}" HorizontalAlignment="Center" Margin="0,0,0,10"/> <!-- ScrollViewer with automatic height management --> <ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled"> <ListBox Name="CameraList" SelectionMode="Single"> <ListBox.ItemTemplate> <DataTemplate> <mdControls:Card Margin="10" Padding="15" HorizontalAlignment="Center"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <TextBlock Grid.Row="0" Grid.Column="0" Text="Hardware Name:" FontWeight="Bold" FontSize="14" Margin="0,0,5,0"/> <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding HardwareName}" FontSize="14"/> <TextBlock Grid.Row="1" Grid.Column="0" Text="Recording Server:" FontWeight="Bold" Margin="0,0,5,0"/> <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding RecordingServer}" /> <TextBlock Grid.Row="2" Grid.Column="0" Text="Stream Name:" FontWeight="Bold" Margin="0,0,5,0"/> <TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding StreamName}" /> <TextBlock Grid.Row="3" Grid.Column="0" Text="Serial:" FontWeight="Bold" Margin="0,0,5,0"/> <TextBlock Grid.Row="3" Grid.Column="1" Text="{Binding Serial}" /> <TextBlock Grid.Row="4" Grid.Column="0" Text="Model:" FontWeight="Bold" Margin="0,0,5,0"/> <TextBlock Grid.Row="4" Grid.Column="1" Text="{Binding Model}" /> <TextBlock Grid.Row="5" Grid.Column="0" Text="Address:" FontWeight="Bold" Margin="0,0,5,0"/> <TextBlock Grid.Row="5" Grid.Column="1" Text="{Binding Address}" /> <TextBlock Grid.Row="6" Grid.Column="0" Text="MAC Address:" FontWeight="Bold" Margin="0,0,5,0"/> <TextBlock Grid.Row="6" Grid.Column="1" Text="{Binding MacAddress}" /> <TextBlock Grid.Row="7" Grid.Column="0" Text="Username:" FontWeight="Bold" Margin="0,0,5,0"/> <TextBlock Grid.Row="7" Grid.Column="1" Text="{Binding Username}" /> <TextBlock Grid.Row="8" Grid.Column="0" Text="Password:" FontWeight="Bold" Margin="0,0,5,0"/> <TextBlock Grid.Row="8" Grid.Column="1" Text="{Binding Password}" /> </Grid> </mdControls:Card> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </ScrollViewer> </Grid> </Window> "@ # Load the XAML and create the window $reader = [System.Xml.XmlNodeReader]::new([xml]$xaml) $window = [System.Windows.Markup.XamlReader]::Load($reader) # Set the window icon if ($null -ne $window) { Set-RpWindowIcon -window $window } else { Write-Warning "WPF window failed to load. Cannot set icon." } # Initialize the ListBox control $cameraList = $window.FindName("CameraList") $cameraList.ItemsSource = $groupedCameras # Event handler for clicking on a ListBox item to copy its details $cameraList.Add_SelectionChanged({ param($sender, $e) $selectedItem = $cameraList.SelectedItem if ($selectedItem) { $selectedText = "" $selectedItem.PSObject.Properties | ForEach-Object { $selectedText += "$($_.Name): $($_.Value)`r`n" } [System.Windows.Clipboard]::SetText($selectedText) } }) # Show the WPF window $window.ShowDialog() | Out-Null } if ($ReturnObjects) { return $groupedCameras } } } |