Private/Invoke-LMSDTResourceWizard.ps1
|
$Script:LMSDTResourceWizardDefinitions = @{ Device = @{ Label = 'device' IdParam = 'DeviceId' NameParam = 'DeviceName' GetById = { param($Id) Get-LMDevice -Id $Id } GetByName = { param($Name) Get-LMDevice -Name $Name } Browse = { Get-LMDevice -BatchSize 100 } DisplayProperty = 'name' IdProperty = 'id' } Collector = @{ Label = 'collector' IdParam = 'CollectorId' NameParam = 'CollectorName' GetById = { param($Id) Get-LMCollector -Id $Id } GetByName = { param($Name) Get-LMCollector -Name $Name } Browse = { Get-LMCollector -BatchSize 100 } DisplayProperty = 'hostname' FilterProperty = 'hostname' IdProperty = 'id' } DeviceGroup = @{ Label = 'device group' IdParam = 'DeviceGroupId' NameParam = 'DeviceGroupName' GetById = { param($Id) Get-LMDeviceGroup -Id $Id } GetByName = { param($Name) Get-LMDeviceGroup -Name $Name } Browse = { Get-LMDeviceGroup -BatchSize 100 } DisplayProperty = 'name' IdProperty = 'id' } Website = @{ Label = 'website' IdParam = 'WebsiteId' NameParam = 'WebsiteName' GetById = { param($Id) Get-LMWebsite -Id $Id } GetByName = { param($Name) Get-LMWebsite -Name $Name } Browse = { Get-LMWebsite -BatchSize 100 } DisplayProperty = 'name' IdProperty = 'id' } WebsiteGroup = @{ Label = 'website group' IdParam = 'WebsiteGroupId' NameParam = 'WebsiteGroupName' GetById = { param($Id) Get-LMWebsiteGroup -Id $Id } GetByName = { param($Name) Get-LMWebsiteGroup -Name $Name } Browse = { Get-LMWebsiteGroup -BatchSize 100 } DisplayProperty = 'name' IdProperty = 'id' } } function Test-LMSDTResourceComplete { [CmdletBinding()] param ( [Parameter(Mandatory)] [ValidateSet('Device', 'Collector', 'DeviceGroup', 'Website', 'WebsiteGroup', 'DeviceDatasource', 'DeviceDatasourceInstance')] [String]$ResourceType, [Parameter(Mandatory)] [hashtable]$BoundParameters ) switch ($ResourceType) { 'DeviceDatasource' { return $BoundParameters.ContainsKey('DeviceDataSourceId') -and -not [string]::IsNullOrWhiteSpace([string]$BoundParameters['DeviceDataSourceId']) } 'DeviceDatasourceInstance' { return $BoundParameters.ContainsKey('DeviceDataSourceInstanceId') -and -not [string]::IsNullOrWhiteSpace([string]$BoundParameters['DeviceDataSourceInstanceId']) } default { $Definition = $Script:LMSDTResourceWizardDefinitions[$ResourceType] $HasId = $BoundParameters.ContainsKey($Definition.IdParam) -and -not [string]::IsNullOrWhiteSpace([string]$BoundParameters[$Definition.IdParam]) $HasName = $BoundParameters.ContainsKey($Definition.NameParam) -and -not [string]::IsNullOrWhiteSpace([string]$BoundParameters[$Definition.NameParam]) return $HasId -or $HasName } } } function Get-LMSDTWizardFilteredBrowseItems { [CmdletBinding()] param ( [Parameter(Mandatory)] [scriptblock]$Browse, [Parameter(Mandatory)] [string]$FilterProperty, [string]$FilterText ) $items = @(& $Browse) if ([string]::IsNullOrWhiteSpace($FilterText)) { return $items } return @($items | Where-Object { $value = $_.($FilterProperty) -not [string]::IsNullOrWhiteSpace([string]$value) -and [string]$value -like "*$FilterText*" }) } function Invoke-LMSDTWizardBrowseSelection { [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Required for interactive wizards')] param ( [Parameter(Mandatory)] [scriptblock]$Browse, [Parameter(Mandatory)] [string]$DisplayProperty, [Parameter(Mandatory)] [string]$IdProperty, [Parameter(Mandatory)] [string]$ResourceLabel, [string]$FilterProperty ) if ([string]::IsNullOrWhiteSpace($FilterProperty)) { $FilterProperty = $DisplayProperty } do { $filterText = Read-LMWizardHost 'Filter by name (leave blank for first page; q to cancel)' $items = Get-LMSDTWizardFilteredBrowseItems -Browse $Browse -FilterProperty $FilterProperty -FilterText $filterText if ($items.Count -eq 0) { Write-Host "No matching $ResourceLabel resources found." -ForegroundColor Yellow continue } $selected = Select-LMResourceFromList -Items $items -DisplayProperty $DisplayProperty -IdProperty $IdProperty -ResourceLabel $ResourceLabel if ($selected) { return $selected } } while ($true) } function Select-LMResourceFromList { [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Required for interactive wizards')] param ( [AllowEmptyCollection()] [array]$Items, [Parameter(Mandatory)] [string]$DisplayProperty, [Parameter(Mandatory)] [string]$IdProperty, [Parameter(Mandatory)] [string]$ResourceLabel ) if ($null -eq $Items -or @($Items).Count -eq 0) { Write-Host "No $ResourceLabel resources found." -ForegroundColor Yellow return $null } $choices = @($Items | ForEach-Object { @{ Name = "$($_.($DisplayProperty)) (ID: $($_.($IdProperty)))" Value = $_ } }) $selected = Get-LMUserSelection -Prompt "Select a $($ResourceLabel):" -Choices $choices -ChoiceLabelProperty 'Name' return $selected.Value } function Write-LMSDTWizardResourceMatch { [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Required for interactive wizards')] param ( [Parameter(Mandatory)] [hashtable]$Definition, [Parameter(Mandatory)] $Resource ) $displayValue = $Resource.($Definition.DisplayProperty) $idValue = $Resource.($Definition.IdProperty) Write-Host "Selected $($Definition.Label): $displayValue (ID: $idValue)" -ForegroundColor Green } function Write-LMSDTWizardSelectionMatch { [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Required for interactive wizards')] param ( [Parameter(Mandatory)] [string]$Label, [Parameter(Mandatory)] [string]$DisplayValue, [Parameter(Mandatory)] [string]$Id ) Write-Host "Selected $Label`: $DisplayValue (ID: $Id)" -ForegroundColor Green } function Get-LMSDTWizardTargetSummaryLines { [CmdletBinding()] param ( [Parameter(Mandatory)] [ValidateSet('Device', 'Collector', 'DeviceGroup', 'Website', 'WebsiteGroup', 'DeviceDatasource', 'DeviceDatasourceInstance')] [String]$ResourceType, [Parameter(Mandatory)] [hashtable]$BoundParameters ) $lines = [System.Collections.Generic.List[string]]::new() switch ($ResourceType) { 'Device' { $deviceId = [string]$BoundParameters['DeviceId'] $device = Get-LMDevice -Id $deviceId -ErrorAction SilentlyContinue if ($device) { $lines.Add("Device: $($device.name) (ID: $($device.id))") } else { $lines.Add("Device ID: $deviceId") } } 'Collector' { $collectorId = [string]$BoundParameters['CollectorId'] $collector = Get-LMCollector -Id $collectorId -ErrorAction SilentlyContinue if ($collector) { $lines.Add("Collector: $($collector.hostname) (ID: $($collector.id))") } else { $lines.Add("Collector ID: $collectorId") } } 'DeviceGroup' { $groupId = [string]$BoundParameters['DeviceGroupId'] $group = Get-LMDeviceGroup -Id $groupId -ErrorAction SilentlyContinue if ($group) { $lines.Add("Device group: $($group.name) (ID: $($group.id))") } else { $lines.Add("Device group ID: $groupId") } } 'Website' { $websiteId = [string]$BoundParameters['WebsiteId'] $website = Get-LMWebsite -Id $websiteId -ErrorAction SilentlyContinue if ($website) { $lines.Add("Website: $($website.name) (ID: $($website.id))") } else { $lines.Add("Website ID: $websiteId") } } 'WebsiteGroup' { $groupId = [string]$BoundParameters['WebsiteGroupId'] $group = Get-LMWebsiteGroup -Id $groupId -ErrorAction SilentlyContinue if ($group) { $lines.Add("Website group: $($group.name) (ID: $($group.id))") } else { $lines.Add("Website group ID: $groupId") } } 'DeviceDatasource' { $deviceId = [string]$BoundParameters['DeviceId'] $device = Get-LMDevice -Id $deviceId -ErrorAction SilentlyContinue if ($device) { $lines.Add("Device: $($device.name) (ID: $($device.id))") } else { $lines.Add("Device ID: $deviceId") } $datasourceId = [string]$BoundParameters['DeviceDataSourceId'] $datasource = @(Get-LMDeviceDataSourceList -Id $deviceId -BatchSize 100 -ErrorAction SilentlyContinue) | Where-Object { [string]$_.id -eq $datasourceId } | Select-Object -First 1 if ($datasource) { $lines.Add("Datasource: $($datasource.dataSourceName) (ID: $($datasource.id))") } else { $lines.Add("Datasource ID: $datasourceId") } } 'DeviceDatasourceInstance' { $deviceId = [string]$BoundParameters['DeviceId'] $device = Get-LMDevice -Id $deviceId -ErrorAction SilentlyContinue if ($device) { $lines.Add("Device: $($device.name) (ID: $($device.id))") } else { $lines.Add("Device ID: $deviceId") } $datasourceId = [string]$BoundParameters['DeviceDataSourceId'] $datasource = @(Get-LMDeviceDataSourceList -Id $deviceId -BatchSize 100 -ErrorAction SilentlyContinue) | Where-Object { [string]$_.id -eq $datasourceId } | Select-Object -First 1 if ($datasource) { $lines.Add("Datasource: $($datasource.dataSourceName) (ID: $($datasource.id))") } else { $lines.Add("Datasource ID: $datasourceId") } $instanceId = [string]$BoundParameters['DeviceDataSourceInstanceId'] $instance = @(Get-LMDeviceDatasourceInstance -Id $deviceId -DatasourceId $datasourceId -BatchSize 100 -ErrorAction SilentlyContinue) | Where-Object { [string]$_.id -eq $instanceId } | Select-Object -First 1 if ($instance) { $lines.Add("Datasource instance: $($instance.displayName) (ID: $($instance.id))") } else { $lines.Add("Datasource instance ID: $instanceId") } } } return @($lines) } function Get-LMSDTWizardResourceById { [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Required for interactive wizards')] param ( [Parameter(Mandatory)] [hashtable]$Definition ) do { $resourceId = Read-LMWizardHost "Enter $($Definition.Label) ID (q to cancel)" $resource = & $Definition.GetById $resourceId if ($resource) { Write-LMSDTWizardResourceMatch -Definition $Definition -Resource $resource return @{ $Definition.IdParam = [string]$resource.($Definition.IdProperty) } } Write-Host "No $($Definition.Label) found with ID '$resourceId'." -ForegroundColor Yellow } while ($true) } function Get-LMSDTWizardResourceByName { [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Required for interactive wizards')] param ( [Parameter(Mandatory)] [hashtable]$Definition ) do { $resourceName = Read-LMWizardHost "Enter $($Definition.Label) name (q to cancel)" $resource = & $Definition.GetByName $resourceName if (-not (Test-LookupResult -Result $resource -LookupString $resourceName)) { Write-LMSDTWizardResourceMatch -Definition $Definition -Resource $resource return @{ $Definition.IdParam = [string]$resource.($Definition.IdProperty) } } Write-Host "No $($Definition.Label) found with name '$resourceName'." -ForegroundColor Yellow } while ($true) } function Invoke-LMSDTWizardResourceSelection { [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Required for interactive wizards')] param ( [Parameter(Mandatory)] [hashtable]$Definition ) do { $methods = @( @{ Name = "Enter $($Definition.Label) ID"; Value = 'Id' } @{ Name = "Enter $($Definition.Label) name"; Value = 'Name' } @{ Name = "Browse $($Definition.Label)s"; Value = 'Browse' } ) $method = Get-LMUserSelection -Prompt "How do you want to select the $($Definition.Label)?" -Choices $methods -ChoiceLabelProperty 'Name' $selection = switch ($method.Value) { 'Id' { Get-LMSDTWizardResourceById -Definition $Definition } 'Name' { Get-LMSDTWizardResourceByName -Definition $Definition } 'Browse' { $filterProperty = if ($Definition.FilterProperty) { $Definition.FilterProperty } else { $Definition.DisplayProperty } $selected = Invoke-LMSDTWizardBrowseSelection ` -Browse $Definition.Browse ` -DisplayProperty $Definition.DisplayProperty ` -IdProperty $Definition.IdProperty ` -ResourceLabel $Definition.Label ` -FilterProperty $filterProperty if ($selected) { Write-LMSDTWizardResourceMatch -Definition $Definition -Resource $selected @{ $Definition.IdParam = [string]$selected.($Definition.IdProperty) } } } } if ($selection) { return $selection } if (-not (Get-LMUserConfirmation -Prompt 'Choose a different selection method?' -DefaultAnswer 'y')) { return $null } } while ($true) } function Invoke-LMSDTDeviceSelection { [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Required for interactive wizards')] param ( [hashtable]$BoundParameters ) if ($BoundParameters.ContainsKey('DeviceId') -and -not [string]::IsNullOrWhiteSpace([string]$BoundParameters['DeviceId'])) { return @{ DeviceId = $BoundParameters['DeviceId'] } } if ($BoundParameters.ContainsKey('DeviceName') -and -not [string]::IsNullOrWhiteSpace([string]$BoundParameters['DeviceName'])) { return @{ DeviceName = $BoundParameters['DeviceName'] } } return Invoke-LMSDTWizardResourceSelection -Definition $Script:LMSDTResourceWizardDefinitions['Device'] } function Invoke-LMSDTSimpleResourceWizard { [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Required for interactive wizards')] param ( [Parameter(Mandatory)] [ValidateSet('Device', 'Collector', 'DeviceGroup', 'Website', 'WebsiteGroup')] [String]$ResourceType ) return Invoke-LMSDTWizardResourceSelection -Definition $Script:LMSDTResourceWizardDefinitions[$ResourceType] } function Invoke-LMSDTDatasourceSelection { [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Required for interactive wizards')] param ( [Parameter(Mandatory)] [String]$DeviceId ) $datasources = @(Get-LMDeviceDataSourceList -Id $DeviceId -BatchSize 25) if ($datasources.Count -eq 0) { Write-Host "No datasources found for device ID '$DeviceId'." -ForegroundColor Yellow return $null } $choices = @($datasources | ForEach-Object { @{ Name = "$($_.dataSourceName) (ID: $($_.id))" Value = $_ } }) $selected = Get-LMUserSelection -Prompt 'Select a device datasource:' -Choices $choices -ChoiceLabelProperty 'Name' Write-LMSDTWizardSelectionMatch -Label 'datasource' -DisplayValue $selected.Value.dataSourceName -Id $selected.Value.id return @{ DeviceDataSourceId = [string]$selected.Value.id } } function Invoke-LMSDTDatasourceInstanceSelection { [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Required for interactive wizards')] param ( [Parameter(Mandatory)] [String]$DeviceId, [Parameter(Mandatory)] [String]$DatasourceId ) $instances = @(Get-LMDeviceDatasourceInstance -Id $DeviceId -DatasourceId $DatasourceId -BatchSize 25) if ($instances.Count -eq 0) { Write-Host "No datasource instances found for device ID '$DeviceId' and datasource ID '$DatasourceId'." -ForegroundColor Yellow return $null } $choices = @($instances | ForEach-Object { @{ Name = "$($_.displayName) (ID: $($_.id))" Value = $_ } }) $selected = Get-LMUserSelection -Prompt 'Select a datasource instance:' -Choices $choices -ChoiceLabelProperty 'Name' Write-LMSDTWizardSelectionMatch -Label 'datasource instance' -DisplayValue $selected.Value.displayName -Id $selected.Value.id return @{ DeviceDataSourceInstanceId = [string]$selected.Value.id } } function Invoke-LMSDTResourceWizard { [CmdletBinding()] param ( [Parameter(Mandatory)] [ValidateSet('Device', 'Collector', 'DeviceGroup', 'Website', 'WebsiteGroup', 'DeviceDatasource', 'DeviceDatasourceInstance')] [String]$ResourceType, [Parameter(Mandatory)] [hashtable]$BoundParameters ) if (Test-LMSDTResourceComplete -ResourceType $ResourceType -BoundParameters $BoundParameters) { return @{} } switch ($ResourceType) { 'DeviceDatasource' { $deviceSelection = Invoke-LMSDTDeviceSelection -BoundParameters $BoundParameters if ($null -eq $deviceSelection) { return $null } $deviceId = $deviceSelection['DeviceId'] if (-not $deviceId -and $deviceSelection.ContainsKey('DeviceName')) { $device = Get-LMDevice -Name $deviceSelection['DeviceName'] if (Test-LookupResult -Result $device -LookupString $deviceSelection['DeviceName']) { Write-Host "No device found with name '$($deviceSelection['DeviceName'])'." -ForegroundColor Yellow return $null } Write-LMSDTWizardResourceMatch -Definition $Script:LMSDTResourceWizardDefinitions['Device'] -Resource $device $deviceId = [string]$device.id } $datasourceSelection = Invoke-LMSDTDatasourceSelection -DeviceId $deviceId if ($null -eq $datasourceSelection) { return $null } return $deviceSelection + $datasourceSelection } 'DeviceDatasourceInstance' { $deviceSelection = Invoke-LMSDTDeviceSelection -BoundParameters $BoundParameters if ($null -eq $deviceSelection) { return $null } $deviceId = $deviceSelection['DeviceId'] if (-not $deviceId -and $deviceSelection.ContainsKey('DeviceName')) { $device = Get-LMDevice -Name $deviceSelection['DeviceName'] if (Test-LookupResult -Result $device -LookupString $deviceSelection['DeviceName']) { Write-Host "No device found with name '$($deviceSelection['DeviceName'])'." -ForegroundColor Yellow return $null } Write-LMSDTWizardResourceMatch -Definition $Script:LMSDTResourceWizardDefinitions['Device'] -Resource $device $deviceId = [string]$device.id } $datasourceSelection = Invoke-LMSDTDatasourceSelection -DeviceId $deviceId if ($null -eq $datasourceSelection) { return $null } $datasourceId = $datasourceSelection['DeviceDataSourceId'] $instanceSelection = Invoke-LMSDTDatasourceInstanceSelection -DeviceId $deviceId -DatasourceId $datasourceId if ($null -eq $instanceSelection) { return $null } return $deviceSelection + $datasourceSelection + $instanceSelection } default { $selection = Invoke-LMSDTSimpleResourceWizard -ResourceType $ResourceType if ($null -eq $selection) { return $null } return $selection } } } function Resolve-LMSDTResourceIdentifiers { [CmdletBinding()] param ( [Parameter(Mandatory)] [ValidateSet('Device', 'Collector', 'DeviceGroup', 'Website', 'WebsiteGroup', 'DeviceDatasource', 'DeviceDatasourceInstance')] [String]$ResourceType, [Parameter(Mandatory)] [hashtable]$BoundParameters ) $Result = @{} foreach ($Key in $BoundParameters.Keys) { $Result[$Key] = $BoundParameters[$Key] } switch ($ResourceType) { 'DeviceDatasource' { if ($Result.ContainsKey('DeviceName') -and -not $Result.ContainsKey('DeviceId')) { $lookup = (Get-LMDevice -Name $Result['DeviceName']).Id if (Test-LookupResult -Result $lookup -LookupString $Result['DeviceName']) { throw "Unable to resolve device name '$($Result['DeviceName'])'." } $Result['DeviceId'] = [string]$lookup } } 'DeviceDatasourceInstance' { if ($Result.ContainsKey('DeviceName') -and -not $Result.ContainsKey('DeviceId')) { $lookup = (Get-LMDevice -Name $Result['DeviceName']).Id if (Test-LookupResult -Result $lookup -LookupString $Result['DeviceName']) { throw "Unable to resolve device name '$($Result['DeviceName'])'." } $Result['DeviceId'] = [string]$lookup } } default { $Definition = $Script:LMSDTResourceWizardDefinitions[$ResourceType] if ($Result.ContainsKey($Definition.NameParam) -and -not $Result.ContainsKey($Definition.IdParam)) { $resource = & $Definition.GetByName $Result[$Definition.NameParam] if (Test-LookupResult -Result $resource -LookupString $Result[$Definition.NameParam]) { throw "Unable to resolve $($Definition.Label) name '$($Result[$Definition.NameParam])'." } $Result[$Definition.IdParam] = [string]$resource.($Definition.IdProperty) } } } return $Result } function Test-LMSDTResourceIdentifiersValid { [CmdletBinding()] param ( [Parameter(Mandatory)] [ValidateSet('Device', 'Collector', 'DeviceGroup', 'Website', 'WebsiteGroup', 'DeviceDatasource', 'DeviceDatasourceInstance')] [String]$ResourceType, [Parameter(Mandatory)] [hashtable]$BoundParameters ) switch ($ResourceType) { 'DeviceDatasource' { if (-not $BoundParameters.ContainsKey('DeviceDataSourceId') -or [string]::IsNullOrWhiteSpace([string]$BoundParameters['DeviceDataSourceId'])) { throw 'DeviceDataSourceId is required.' } } 'DeviceDatasourceInstance' { if (-not $BoundParameters.ContainsKey('DeviceDataSourceInstanceId') -or [string]::IsNullOrWhiteSpace([string]$BoundParameters['DeviceDataSourceInstanceId'])) { throw 'DeviceDataSourceInstanceId is required.' } } default { $Definition = $Script:LMSDTResourceWizardDefinitions[$ResourceType] $HasId = $BoundParameters.ContainsKey($Definition.IdParam) -and -not [string]::IsNullOrWhiteSpace([string]$BoundParameters[$Definition.IdParam]) $HasName = $BoundParameters.ContainsKey($Definition.NameParam) -and -not [string]::IsNullOrWhiteSpace([string]$BoundParameters[$Definition.NameParam]) if ($HasId -and $HasName) { throw "Provide either -$($Definition.IdParam) or -$($Definition.NameParam), not both." } if (-not $HasId -and -not $HasName) { throw "Either -$($Definition.IdParam) or -$($Definition.NameParam) is required." } } } } |