customplatforms.psm1
|
<# Copyright (c) 2026 One Identity LLC. All rights reserved. #> <# .SYNOPSIS Get custom platform definitions from Safeguard via the Web API. .DESCRIPTION Get the custom platform definitions that have been created in Safeguard. Custom platforms have PlatformFamily=Custom and are user-defined rather than built-in. This cmdlet can return all custom platforms or a specific one by ID or name. .PARAMETER Appliance IP address or hostname of a Safeguard appliance. .PARAMETER AccessToken A string containing the bearer token to be used with Safeguard Web API. .PARAMETER Insecure Ignore verification of Safeguard appliance SSL certificate. .PARAMETER PlatformToGet An integer containing the platform ID or a string containing the platform display name of the custom platform to return. .PARAMETER Fields An array of the platform property names to return. .INPUTS None. .OUTPUTS JSON response from Safeguard Web API. .EXAMPLE Get-SafeguardCustomPlatform -AccessToken $token -Appliance 10.5.32.54 -Insecure .EXAMPLE Get-SafeguardCustomPlatform .EXAMPLE Get-SafeguardCustomPlatform "My Custom Platform" .EXAMPLE Get-SafeguardCustomPlatform 65536 #> function Get-SafeguardCustomPlatform { [CmdletBinding()] Param( [Parameter(Mandatory=$false)] [string]$Appliance, [Parameter(Mandatory=$false)] [object]$AccessToken, [Parameter(Mandatory=$false)] [switch]$Insecure, [Parameter(Mandatory=$false,Position=0)] [object]$PlatformToGet, [Parameter(Mandatory=$false)] [string[]]$Fields ) if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" } if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") } $local:Parameters = @{ filter = "PlatformFamily eq 'Custom'"; orderby = "Id" } if ($Fields) { $local:Parameters["fields"] = ($Fields -join ",") } if ($PSBoundParameters.ContainsKey("PlatformToGet")) { if ($PlatformToGet -as [int]) { $local:Result = (Invoke-SafeguardMethod -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure Core ` GET "Platforms/$($PlatformToGet -as [int])") if ($local:Result.PlatformFamily -ne "Custom") { throw "Platform '$PlatformToGet' is not a custom platform (PlatformFamily=$($local:Result.PlatformFamily))" } $local:Result } else { $local:Parameters["filter"] = "PlatformFamily eq 'Custom' and DisplayName icontains '$PlatformToGet'" $local:Results = (Invoke-SafeguardMethod -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure Core ` GET Platforms -Parameters $local:Parameters) if (-not $local:Results) { throw "Unable to find custom platform matching '$PlatformToGet'" } if ($local:Results -is [array] -and $local:Results.Count -ne 1) { throw "Found $($local:Results.Count) custom platforms matching '$PlatformToGet'" } $local:Results } } else { Invoke-SafeguardMethod -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure Core ` GET Platforms -Parameters $local:Parameters } } <# .SYNOPSIS Create a new custom platform in Safeguard via the Web API. .DESCRIPTION Create a new custom platform definition in Safeguard. Custom platforms have PlatformFamily=Custom and PlatformType=Custom. Optionally upload a platform script file at creation time. .PARAMETER Appliance IP address or hostname of a Safeguard appliance. .PARAMETER AccessToken A string containing the bearer token to be used with Safeguard Web API. .PARAMETER Insecure Ignore verification of Safeguard appliance SSL certificate. .PARAMETER Name A string containing the name for the new custom platform. .PARAMETER DisplayName A string containing the display name for the new custom platform. If not specified, defaults to the Name value. .PARAMETER Description A string containing the description for the new custom platform. .PARAMETER ScriptFile A string containing the path to a JSON platform script file to upload after creating the platform. The script will be uploaded via the Platforms/{id}/Script/Raw endpoint. .PARAMETER AllowSessionRequests When specified, enables session management (SupportsSessionManagement) on the custom platform, allowing session access requests for assets using this platform. .PARAMETER SshSessionPort An integer containing the default SSH session port for the custom platform. This is typically 22. Only meaningful when -AllowSessionRequests is also specified. .PARAMETER RdpSessionPort An integer containing the default Remote Desktop session port for the custom platform. This is typically 3389. .PARAMETER TelnetSessionPort An integer containing the default Telnet session port for the custom platform. .INPUTS None. .OUTPUTS JSON response from Safeguard Web API. .EXAMPLE New-SafeguardCustomPlatform "My Custom Linux" .EXAMPLE New-SafeguardCustomPlatform -Name "My Custom Linux" -Description "Custom SSH platform" -ScriptFile "C:\scripts\MyScript.json" .EXAMPLE New-SafeguardCustomPlatform -Name "My Custom Linux" -AllowSessionRequests -SshSessionPort 22 #> function New-SafeguardCustomPlatform { [CmdletBinding()] Param( [Parameter(Mandatory=$false)] [string]$Appliance, [Parameter(Mandatory=$false)] [object]$AccessToken, [Parameter(Mandatory=$false)] [switch]$Insecure, [Parameter(Mandatory=$true,Position=0)] [string]$Name, [Parameter(Mandatory=$false)] [string]$DisplayName, [Parameter(Mandatory=$false)] [string]$Description, [Parameter(Mandatory=$false)] [string]$ScriptFile, [Parameter(Mandatory=$false)] [switch]$AllowSessionRequests, [Parameter(Mandatory=$false)] [int]$SshSessionPort, [Parameter(Mandatory=$false)] [int]$RdpSessionPort, [Parameter(Mandatory=$false)] [int]$TelnetSessionPort ) if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" } if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") } $local:DisplayNameValue = $Name if ($PSBoundParameters.ContainsKey("DisplayName")) { $local:DisplayNameValue = $DisplayName } $local:Body = @{ Name = $Name; DisplayName = $local:DisplayNameValue; PlatformType = "Custom"; PlatformFamily = "Custom" } if ($PSBoundParameters.ContainsKey("Description")) { $local:Body.Description = $Description } $local:Result = (Invoke-SafeguardMethod -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure Core ` POST Platforms -Body $local:Body) # Session and script settings require a PUT after creation $local:NeedsUpdate = $false if ($AllowSessionRequests) { $local:Result.SessionFeatureProperties.SupportsSessionManagement = $true $local:NeedsUpdate = $true } if ($PSBoundParameters.ContainsKey("SshSessionPort")) { $local:Result.SessionFeatureProperties.DefaultSshSessionPort = $SshSessionPort $local:NeedsUpdate = $true } if ($PSBoundParameters.ContainsKey("RdpSessionPort")) { $local:Result.SessionFeatureProperties.DefaultRemoteDesktopSessionPort = $RdpSessionPort $local:NeedsUpdate = $true } if ($PSBoundParameters.ContainsKey("TelnetSessionPort")) { $local:Result.SessionFeatureProperties.DefaultTelnetSessionPort = $TelnetSessionPort $local:NeedsUpdate = $true } if ($local:NeedsUpdate) { $local:Result = (Invoke-SafeguardMethod -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure Core ` PUT "Platforms/$($local:Result.Id)" -Body $local:Result) } if ($PSBoundParameters.ContainsKey("ScriptFile")) { if (-not (Test-Path $ScriptFile)) { throw "Script file not found: $ScriptFile" } $local:ScriptContent = (Get-Content -Path $ScriptFile -Raw) Invoke-SafeguardMethod -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure Core ` PUT "Platforms/$($local:Result.Id)/Script/Raw" -ContentType "application/octet-stream" -JsonBody $local:ScriptContent | Out-Null # Re-fetch to return updated platform with script info $local:Result = (Invoke-SafeguardMethod -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure Core ` GET "Platforms/$($local:Result.Id)") } $local:Result } <# .SYNOPSIS Edit an existing custom platform in Safeguard via the Web API. .DESCRIPTION Edit an existing custom platform definition in Safeguard. You can modify individual properties or pipe a full platform object with modifications. Optionally upload or replace the platform script file. .PARAMETER Appliance IP address or hostname of a Safeguard appliance. .PARAMETER AccessToken A string containing the bearer token to be used with Safeguard Web API. .PARAMETER Insecure Ignore verification of Safeguard appliance SSL certificate. .PARAMETER PlatformToEdit An integer containing the platform ID or a string containing the platform display name of the custom platform to edit. .PARAMETER Name A string containing the new name for the custom platform. .PARAMETER DisplayName A string containing the new display name for the custom platform. .PARAMETER Description A string containing the new description for the custom platform. .PARAMETER ScriptFile A string containing the path to a JSON platform script file to upload, replacing any existing script on the platform. .PARAMETER AllowSessionRequests When specified, enables session management (SupportsSessionManagement) on the custom platform, allowing session access requests for assets using this platform. .PARAMETER DenySessionRequests When specified, disables session management (SupportsSessionManagement) on the custom platform. .PARAMETER SshSessionPort An integer containing the default SSH session port for the custom platform. .PARAMETER RdpSessionPort An integer containing the default Remote Desktop session port for the custom platform. .PARAMETER TelnetSessionPort An integer containing the default Telnet session port for the custom platform. .PARAMETER PlatformObject An object containing the full custom platform object to PUT to the server. This is typically obtained by piping Get-SafeguardCustomPlatform output. .INPUTS None. .OUTPUTS JSON response from Safeguard Web API. .EXAMPLE Edit-SafeguardCustomPlatform 10001 -Description "Updated description" .EXAMPLE Edit-SafeguardCustomPlatform "My Custom Linux" -Name "Renamed Platform" .EXAMPLE Edit-SafeguardCustomPlatform 10001 -AllowSessionRequests -SshSessionPort 22 .EXAMPLE Get-SafeguardCustomPlatform "My Custom Linux" | Edit-SafeguardCustomPlatform .EXAMPLE Edit-SafeguardCustomPlatform 10001 -ScriptFile "C:\scripts\UpdatedScript.json" #> function Edit-SafeguardCustomPlatform { [CmdletBinding()] Param( [Parameter(Mandatory=$false)] [string]$Appliance, [Parameter(Mandatory=$false)] [object]$AccessToken, [Parameter(Mandatory=$false)] [switch]$Insecure, [Parameter(Mandatory=$false,Position=0)] [object]$PlatformToEdit, [Parameter(Mandatory=$false)] [string]$Name, [Parameter(Mandatory=$false)] [string]$DisplayName, [Parameter(Mandatory=$false)] [string]$Description, [Parameter(Mandatory=$false)] [string]$ScriptFile, [Parameter(Mandatory=$false)] [switch]$AllowSessionRequests, [Parameter(Mandatory=$false)] [switch]$DenySessionRequests, [Parameter(Mandatory=$false)] [int]$SshSessionPort, [Parameter(Mandatory=$false)] [int]$RdpSessionPort, [Parameter(Mandatory=$false)] [int]$TelnetSessionPort, [Parameter(Mandatory=$false,ValueFromPipeline=$true)] [object]$PlatformObject ) begin { if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" } if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") } } process { if ($PlatformObject) { if ($PlatformObject.PlatformFamily -ne "Custom") { throw "Platform '$($PlatformObject.DisplayName)' is not a custom platform (PlatformFamily=$($PlatformObject.PlatformFamily))" } $local:PlatformObj = $PlatformObject } else { if (-not $PSBoundParameters.ContainsKey("PlatformToEdit")) { $PlatformToEdit = (Read-Host "PlatformToEdit") } $local:PlatformObj = (Get-SafeguardCustomPlatform -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure $PlatformToEdit) } if ($PSBoundParameters.ContainsKey("Name")) { $local:PlatformObj.Name = $Name } if ($PSBoundParameters.ContainsKey("DisplayName")) { $local:PlatformObj.DisplayName = $DisplayName } if ($PSBoundParameters.ContainsKey("Description")) { $local:PlatformObj.Description = $Description } if ($AllowSessionRequests) { $local:PlatformObj.SessionFeatureProperties.SupportsSessionManagement = $true } if ($DenySessionRequests) { $local:PlatformObj.SessionFeatureProperties.SupportsSessionManagement = $false } if ($PSBoundParameters.ContainsKey("SshSessionPort")) { $local:PlatformObj.SessionFeatureProperties.DefaultSshSessionPort = $SshSessionPort } if ($PSBoundParameters.ContainsKey("RdpSessionPort")) { $local:PlatformObj.SessionFeatureProperties.DefaultRemoteDesktopSessionPort = $RdpSessionPort } if ($PSBoundParameters.ContainsKey("TelnetSessionPort")) { $local:PlatformObj.SessionFeatureProperties.DefaultTelnetSessionPort = $TelnetSessionPort } $local:Result = (Invoke-SafeguardMethod -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure Core ` PUT "Platforms/$($local:PlatformObj.Id)" -Body $local:PlatformObj) if ($PSBoundParameters.ContainsKey("ScriptFile")) { if (-not (Test-Path $ScriptFile)) { throw "Script file not found: $ScriptFile" } $local:ScriptContent = (Get-Content -Path $ScriptFile -Raw) Invoke-SafeguardMethod -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure Core ` PUT "Platforms/$($local:Result.Id)/Script/Raw" -ContentType "application/octet-stream" -JsonBody $local:ScriptContent | Out-Null # Re-fetch to return updated platform with script info $local:Result = (Invoke-SafeguardMethod -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure Core ` GET "Platforms/$($local:Result.Id)") } $local:Result } } <# .SYNOPSIS Remove a custom platform from Safeguard via the Web API. .DESCRIPTION Remove a custom platform definition from Safeguard. This is a permanent deletion. Use -ForceDelete to remove the platform even if it has associated assets or other dependencies. .PARAMETER Appliance IP address or hostname of a Safeguard appliance. .PARAMETER AccessToken A string containing the bearer token to be used with Safeguard Web API. .PARAMETER Insecure Ignore verification of Safeguard appliance SSL certificate. .PARAMETER PlatformToDelete An integer containing the platform ID or a string containing the platform display name of the custom platform to remove. .PARAMETER ForceDelete Remove the custom platform even if it has dependencies (e.g., associated assets). .INPUTS None. .OUTPUTS JSON response from Safeguard Web API. .EXAMPLE Remove-SafeguardCustomPlatform 10001 .EXAMPLE Remove-SafeguardCustomPlatform "My Custom Linux" .EXAMPLE Remove-SafeguardCustomPlatform "My Custom Linux" -ForceDelete #> function Remove-SafeguardCustomPlatform { [CmdletBinding()] Param( [Parameter(Mandatory=$false)] [string]$Appliance, [Parameter(Mandatory=$false)] [object]$AccessToken, [Parameter(Mandatory=$false)] [switch]$Insecure, [Parameter(Mandatory=$false,Position=0)] [object]$PlatformToDelete, [Parameter(Mandatory=$false)] [switch]$ForceDelete ) if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" } if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") } if (-not $PSBoundParameters.ContainsKey("PlatformToDelete")) { $PlatformToDelete = (Read-Host "PlatformToDelete") } $local:Platform = (Get-SafeguardCustomPlatform -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure $PlatformToDelete) $local:Parameters = $null if ($ForceDelete) { $local:Parameters = @{ forceDelete = $true } } Invoke-SafeguardMethod -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure Core ` DELETE "Platforms/$($local:Platform.Id)" -Parameters $local:Parameters } <# .SYNOPSIS Export a custom platform script from Safeguard via the Web API. .DESCRIPTION Retrieve the raw JSON script content from a custom platform. The script can be returned as a string or written directly to a file using -OutFile. .PARAMETER Appliance IP address or hostname of a Safeguard appliance. .PARAMETER AccessToken A string containing the bearer token to be used with Safeguard Web API. .PARAMETER Insecure Ignore verification of Safeguard appliance SSL certificate. .PARAMETER PlatformToGet An integer containing the platform ID or a string containing the platform display name of the custom platform whose script to export. .PARAMETER OutFile A string containing the file path to write the script content to. If not specified, the raw script JSON string is returned. .INPUTS None. .OUTPUTS PSCustomObject representing the script content, or nothing if -OutFile is used. When -OutFile is specified, the JSON is written to the file. .EXAMPLE Export-SafeguardCustomPlatformScript -Insecure "My Custom Linux" .EXAMPLE Export-SafeguardCustomPlatformScript -Insecure 10001 -OutFile "C:\scripts\MyScript.json" #> function Export-SafeguardCustomPlatformScript { [CmdletBinding()] Param( [Parameter(Mandatory=$false)] [string]$Appliance, [Parameter(Mandatory=$false)] [object]$AccessToken, [Parameter(Mandatory=$false)] [switch]$Insecure, [Parameter(Mandatory=$true,Position=0)] [object]$PlatformToGet, [Parameter(Mandatory=$false)] [string]$OutFile ) if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" } if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") } $local:Platform = (Get-SafeguardCustomPlatform -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure $PlatformToGet) if (-not $local:Platform.CustomScriptProperties.HasScript) { throw "Custom platform '$($local:Platform.Name)' (Id=$($local:Platform.Id)) does not have a script" } $local:ScriptContent = (Invoke-SafeguardMethod -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure Core ` GET "Platforms/$($local:Platform.Id)/Script/Raw") if ($PSBoundParameters.ContainsKey("OutFile")) { ($local:ScriptContent | ConvertTo-Json -Depth 100) | Out-File -FilePath $OutFile -Encoding utf8 -NoNewline } else { $local:ScriptContent } } <# .SYNOPSIS Import a platform script into a custom platform in Safeguard via the Web API. .DESCRIPTION Upload a JSON platform script file to a custom platform, replacing any existing script. The script defines the operations the platform supports (e.g., CheckPassword, ChangePassword, DiscoverAccounts). .PARAMETER Appliance IP address or hostname of a Safeguard appliance. .PARAMETER AccessToken A string containing the bearer token to be used with Safeguard Web API. .PARAMETER Insecure Ignore verification of Safeguard appliance SSL certificate. .PARAMETER PlatformToEdit An integer containing the platform ID or a string containing the platform display name of the custom platform to import the script into. .PARAMETER ScriptFile A string containing the path to the JSON platform script file to upload. .INPUTS None. .OUTPUTS JSON response from Safeguard Web API (the updated platform object). .EXAMPLE Import-SafeguardCustomPlatformScript -Insecure "My Custom Linux" -ScriptFile "C:\scripts\MyScript.json" .EXAMPLE Import-SafeguardCustomPlatformScript -Insecure 10001 -ScriptFile "C:\scripts\MyScript.json" #> function Import-SafeguardCustomPlatformScript { [CmdletBinding()] Param( [Parameter(Mandatory=$false)] [string]$Appliance, [Parameter(Mandatory=$false)] [object]$AccessToken, [Parameter(Mandatory=$false)] [switch]$Insecure, [Parameter(Mandatory=$true,Position=0)] [object]$PlatformToEdit, [Parameter(Mandatory=$true,Position=1)] [string]$ScriptFile ) if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" } if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") } $local:Platform = (Get-SafeguardCustomPlatform -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure $PlatformToEdit) if (-not (Test-Path $ScriptFile)) { throw "Script file not found: $ScriptFile" } $local:ScriptContent = (Get-Content -Path $ScriptFile -Raw) Invoke-SafeguardMethod -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure Core ` PUT "Platforms/$($local:Platform.Id)/Script/Raw" -ContentType "application/octet-stream" -JsonBody $local:ScriptContent | Out-Null # Return the updated platform object Get-SafeguardCustomPlatform -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure $local:Platform.Id } <# .SYNOPSIS Validate a custom platform script file via the Safeguard Web API without creating a platform. .DESCRIPTION Submit a JSON platform script file to the Safeguard appliance for validation. The appliance parses the script and checks for structural correctness, required fields, and valid operation definitions. If the script is valid, a platform object preview is returned showing the operations and properties the script would produce. If the script is invalid, an error is thrown with details about the problem. This cmdlet does not create or modify any platform -- it is a dry-run validation. .PARAMETER Appliance IP address or hostname of a Safeguard appliance. .PARAMETER AccessToken A string containing the bearer token to be used with Safeguard Web API. .PARAMETER Insecure Ignore verification of Safeguard appliance SSL certificate. .PARAMETER ScriptFile A string containing the path to a JSON platform script file to validate. .INPUTS None. .OUTPUTS JSON response from Safeguard Web API representing the platform that would be created from this script, including SupportedOperations and ConnectionProperties. .EXAMPLE Test-SafeguardCustomPlatformScript "C:\scripts\MyScript.json" .EXAMPLE Test-SafeguardCustomPlatformScript -ScriptFile "C:\scripts\MyScript.json" -Insecure #> function Test-SafeguardCustomPlatformScript { [CmdletBinding()] Param( [Parameter(Mandatory=$false)] [string]$Appliance, [Parameter(Mandatory=$false)] [object]$AccessToken, [Parameter(Mandatory=$false)] [switch]$Insecure, [Parameter(Mandatory=$true,Position=0)] [string]$ScriptFile ) if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" } if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") } if (-not (Test-Path $ScriptFile)) { throw "Script file not found: $ScriptFile" } $local:ScriptContent = (Get-Content -Path $ScriptFile -Raw) Invoke-SafeguardMethod -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure Core ` POST "Platforms/ValidateScript/Raw" -ContentType "application/octet-stream" -JsonBody $local:ScriptContent } <# .SYNOPSIS Get the custom script parameter definitions from a custom platform or script file in Safeguard via the Web API. .DESCRIPTION Retrieve the custom script parameter schema defined by a custom platform's script. These are the custom (non-well-known) parameters that can be configured per-asset when using this custom platform. Each parameter has a Name, Type, DefaultValue, and TaskName (the operation it applies to). When -ScriptFile is specified, the script is validated without creating a platform, allowing you to discover parameters before platform creation. .PARAMETER Appliance IP address or hostname of a Safeguard appliance. .PARAMETER AccessToken A string containing the bearer token to be used with Safeguard Web API. .PARAMETER Insecure Ignore verification of Safeguard appliance SSL certificate. .PARAMETER Platform An integer containing the platform ID or a string containing the platform display name of the custom platform to query. .PARAMETER ScriptFile Path to a custom platform script JSON file. The script is validated via the API and its parameters are returned without creating a platform. .INPUTS None. .OUTPUTS JSON response from Safeguard Web API -- array of parameter definitions with Name, Description, DefaultValue, Type, and TaskName properties. .EXAMPLE Get-SafeguardCustomPlatformScriptParameter "My Custom Linux" .EXAMPLE Get-SafeguardCustomPlatformScriptParameter 10022 .EXAMPLE Get-SafeguardCustomPlatformScriptParameter -ScriptFile ".\MyScript.json" #> function Get-SafeguardCustomPlatformScriptParameter { [CmdletBinding(DefaultParameterSetName="ByPlatform")] [OutputType([object[]])] Param( [Parameter(Mandatory=$false)] [string]$Appliance, [Parameter(Mandatory=$false)] [object]$AccessToken, [Parameter(Mandatory=$false)] [switch]$Insecure, [Parameter(ParameterSetName="ByPlatform",Mandatory=$true,Position=0)] [object]$Platform, [Parameter(ParameterSetName="ByScriptFile",Mandatory=$true)] [string]$ScriptFile ) if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" } if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") } if ($PSCmdlet.ParameterSetName -eq "ByScriptFile") { if (-not (Test-Path $ScriptFile)) { throw "Script file not found: $ScriptFile" } $local:ScriptContent = (Get-Content -Path $ScriptFile -Raw) $local:Result = (Invoke-SafeguardMethod -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure Core ` POST "Platforms/ValidateScript/Raw" -ContentType "application/octet-stream" -JsonBody $local:ScriptContent) if (-not $local:Result.CustomScriptProperties -or -not $local:Result.CustomScriptProperties.Parameters -or $local:Result.CustomScriptProperties.Parameters.Count -eq 0) { Write-Verbose "Script file '$ScriptFile' has no custom parameters" return @() } $local:Result.CustomScriptProperties.Parameters } else { $local:PlatformObj = (Get-SafeguardCustomPlatform -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure $Platform) if (-not $local:PlatformObj.CustomScriptProperties -or -not $local:PlatformObj.CustomScriptProperties.HasScript) { throw "Custom platform '$Platform' does not have a script uploaded" } if (-not $local:PlatformObj.CustomScriptProperties.Parameters -or $local:PlatformObj.CustomScriptProperties.Parameters.Count -eq 0) { Write-Verbose "Custom platform '$Platform' has a script but no custom parameters" return @() } $local:PlatformObj.CustomScriptProperties.Parameters } } <# .SYNOPSIS Create a new asset using a custom platform in Safeguard via the Web API. .DESCRIPTION Create an asset that uses a custom platform definition. This cmdlet handles the standard asset creation properties (network address, service account, etc.) and also supports setting custom script parameters defined by the platform's script. In interactive mode (when -CustomScriptParameters is not provided), the cmdlet will discover the platform's custom parameters and prompt for values. In automated mode, pass an array of parameter override hashtables. .PARAMETER Appliance IP address or hostname of a Safeguard appliance. .PARAMETER AccessToken A string containing the bearer token to be used with Safeguard Web API. .PARAMETER Insecure Ignore verification of Safeguard appliance SSL certificate. .PARAMETER Platform An integer containing the platform ID or a string containing the platform display name of the custom platform to use. Must be a custom platform. .PARAMETER NetworkAddress A string containing the network address (IP or hostname) of the asset. .PARAMETER DisplayName A string containing the display name for the asset. Defaults to NetworkAddress. .PARAMETER Description A string containing the description for the asset. .PARAMETER AssetPartition An integer or string identifying the asset partition to use. .PARAMETER AssetPartitionId An integer containing the asset partition ID. Use -1 for the default partition. .PARAMETER Port An integer containing the port for connecting to the asset. .PARAMETER ServiceAccountCredentialType A string containing the credential type for the service account. .PARAMETER ServiceAccountName A string containing the service account name. .PARAMETER ServiceAccountPassword A SecureString containing the service account password. .PARAMETER NoSshHostKeyDiscovery Do not attempt SSH host key discovery after asset creation. .PARAMETER AcceptSshHostKey Automatically accept the discovered SSH host key. .PARAMETER CustomScriptParameters An array of hashtables specifying custom script parameter overrides. Each hashtable should contain Name and Value keys. Optionally include TaskName to target a specific operation. If TaskName is omitted, the value is applied to all operations that use that parameter name. .INPUTS None. .OUTPUTS JSON response from Safeguard Web API. .EXAMPLE New-SafeguardCustomPlatformAsset "My Custom Linux" "10.0.0.1" .EXAMPLE New-SafeguardCustomPlatformAsset "My Custom Linux" "10.0.0.1" -CustomScriptParameters @(@{Name="RequestTerminal";Value="False"}) .EXAMPLE New-SafeguardCustomPlatformAsset -Platform 10022 -NetworkAddress "10.0.0.1" -Port 2222 -ServiceAccountCredentialType Password -ServiceAccountName "root" #> function New-SafeguardCustomPlatformAsset { [CmdletBinding()] Param( [Parameter(Mandatory=$false)] [string]$Appliance, [Parameter(Mandatory=$false)] [object]$AccessToken, [Parameter(Mandatory=$false)] [switch]$Insecure, [Parameter(Mandatory=$true,Position=0)] [object]$Platform, [Parameter(Mandatory=$true,Position=1)] [string]$NetworkAddress, [Parameter(Mandatory=$false)] [string]$DisplayName, [Parameter(Mandatory=$false)] [string]$Description, [Parameter(Mandatory=$false)] [object]$AssetPartition, [Parameter(Mandatory=$false)] [int]$AssetPartitionId = $null, [Parameter(Mandatory=$false)] [int]$Port, [Parameter(Mandatory=$false)] [ValidateSet("None","Password","SshKey","DirectoryPassword","LocalHostPassword","AccessKey","AccountPassword","Custom",IgnoreCase=$true)] [string]$ServiceAccountCredentialType, [Parameter(Mandatory=$false)] [string]$ServiceAccountName, [Parameter(Mandatory=$false)] [SecureString]$ServiceAccountPassword, [Parameter(Mandatory=$false)] [switch]$NoSshHostKeyDiscovery, [Parameter(Mandatory=$false)] [switch]$AcceptSshHostKey, [Parameter(Mandatory=$false)] [hashtable[]]$CustomScriptParameters ) if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" } if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") } Import-Module -Name "$PSScriptRoot\ps-utilities.psm1" -Scope Local Import-Module -Name "$PSScriptRoot\datatypes.psm1" -Scope Local # Resolve the custom platform $local:PlatformObj = (Get-SafeguardCustomPlatform -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure $Platform) if (-not $PSBoundParameters.ContainsKey("DisplayName") -or [string]::IsNullOrEmpty($DisplayName)) { if ([string]::IsNullOrEmpty($NetworkAddress) -or (Test-IpAddress $NetworkAddress)) { $DisplayName = (Read-Host "DisplayName") } else { $DisplayName = $NetworkAddress } } # Build connection properties $local:ConnectionProperties = @{} if ($PSBoundParameters.ContainsKey("Port")) { $local:ConnectionProperties.Port = $Port } if (-not $PSBoundParameters.ContainsKey("ServiceAccountCredentialType")) { $ServiceAccountCredentialType = "None" } $local:ConnectionProperties.ServiceAccountCredentialType = $ServiceAccountCredentialType if ($ServiceAccountCredentialType -ne "None") { switch ($ServiceAccountCredentialType.ToLower()) { "password" { if (-not $PSBoundParameters.ContainsKey("ServiceAccountName") -or -not $ServiceAccountName) { $ServiceAccountName = (Read-Host "ServiceAccountName") } $local:ConnectionProperties.ServiceAccountName = $ServiceAccountName if (-not $PSBoundParameters.ContainsKey("ServiceAccountPassword")) { $ServiceAccountPassword = (Read-Host -AsSecureString "ServiceAccountPassword") } $local:ConnectionProperties.ServiceAccountPassword = ` [System.Net.NetworkCredential]::new("", $ServiceAccountPassword).Password } default { if (-not $PSBoundParameters.ContainsKey("ServiceAccountName") -or -not $ServiceAccountName) { $ServiceAccountName = (Read-Host "ServiceAccountName") } $local:ConnectionProperties.ServiceAccountName = $ServiceAccountName } } } # Resolve asset partition Import-Module -Name "$PSScriptRoot\assetpartitions.psm1" -Scope Local $AssetPartitionId = (Resolve-AssetPartitionIdFromSafeguardSession -Appliance $Appliance -AccessToken $AccessToken -Insecure:$Insecure ` -AssetPartition $AssetPartition -AssetPartitionId $AssetPartitionId -UseDefault) # Create the asset $local:Body = @{ Name = "$DisplayName"; Description = "$Description"; NetworkAddress = "$NetworkAddress"; PlatformId = $local:PlatformObj.Id; AssetPartitionId = $AssetPartitionId; ConnectionProperties = $local:ConnectionProperties; } $local:NewAsset = (Invoke-SafeguardMethod -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure Core ` POST Assets -Body $local:Body) # Handle custom script parameter overrides (POST-then-PUT pattern) $local:HasCustomParamOverrides = $false $local:ScriptParams = $local:PlatformObj.CustomScriptProperties.Parameters if ($PSBoundParameters.ContainsKey("CustomScriptParameters") -and $CustomScriptParameters) { # Automated mode: apply overrides from the parameter $local:HasCustomParamOverrides = $true } elseif ($local:ScriptParams -and $local:ScriptParams.Count -gt 0 -and -not $PSBoundParameters.ContainsKey("CustomScriptParameters")) { # Interactive mode: prompt for each unique parameter $local:UniqueParams = @{} foreach ($local:Param in $local:ScriptParams) { if (-not $local:UniqueParams.ContainsKey($local:Param.Name)) { $local:UniqueParams[$local:Param.Name] = $local:Param } } $local:InteractiveOverrides = @() foreach ($local:ParamName in $local:UniqueParams.Keys) { $local:ParamDef = $local:UniqueParams[$local:ParamName] $local:Prompt = "$local:ParamName [$($local:ParamDef.Type)] (default: $($local:ParamDef.DefaultValue))" $local:UserValue = (Read-Host $local:Prompt) if (-not [string]::IsNullOrEmpty($local:UserValue)) { $local:InteractiveOverrides += @{ Name = $local:ParamName; Value = $local:UserValue } } } if ($local:InteractiveOverrides.Count -gt 0) { $CustomScriptParameters = $local:InteractiveOverrides $local:HasCustomParamOverrides = $true } } if ($local:HasCustomParamOverrides) { try { # GET-then-PUT to apply custom parameter overrides $local:AssetObj = (Invoke-SafeguardMethod -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure Core ` GET "Assets/$($local:NewAsset.Id)") if ($local:AssetObj.CustomScriptParameters) { foreach ($local:Override in $CustomScriptParameters) { $local:OverrideName = $local:Override.Name $local:OverrideValue = $local:Override.Value $local:OverrideTaskName = $null if ($local:Override.ContainsKey("TaskName")) { $local:OverrideTaskName = $local:Override.TaskName } foreach ($local:AssetParam in $local:AssetObj.CustomScriptParameters) { if ($local:AssetParam.Name -eq $local:OverrideName) { if ($local:OverrideTaskName -and $local:AssetParam.TaskName -ne $local:OverrideTaskName) { continue } $local:AssetParam.Value = "$local:OverrideValue" } } } $local:NewAsset = (Invoke-SafeguardMethod -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure Core ` PUT "Assets/$($local:NewAsset.Id)" -Body $local:AssetObj) } } catch { Write-Host -ForegroundColor Yellow "Error setting custom script parameters, removing asset..." Invoke-SafeguardMethod -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure Core ` DELETE "Assets/$($local:NewAsset.Id)" | Out-Null throw } } # Handle SSH host key discovery try { if ($local:NewAsset.Platform.ConnectionProperties.SupportsSshTransport -and -not $NoSshHostKeyDiscovery) { Import-Module -Name "$PSScriptRoot\assets.psm1" -Scope Local Invoke-SafeguardAssetSshHostKeyDiscovery -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure $local:NewAsset -AcceptSshHostKey:$AcceptSshHostKey } else { $local:NewAsset } } catch { Write-Host -ForegroundColor Yellow "Error setting up SSH host key, removing asset..." Invoke-SafeguardMethod -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure Core ` DELETE "Assets/$($local:NewAsset.Id)" | Out-Null throw } } <# .SYNOPSIS Set a custom script parameter value on a Safeguard asset via the Web API. .DESCRIPTION Modify one or more custom script parameter values on an existing asset that uses a custom platform. Uses the GET-then-PUT pattern to update the asset's CustomScriptParameters array. When TaskName is specified, only the parameter for that specific operation is updated. When TaskName is omitted, all operations that use the specified parameter name are updated to the new value. .PARAMETER Appliance IP address or hostname of a Safeguard appliance. .PARAMETER AccessToken A string containing the bearer token to be used with Safeguard Web API. .PARAMETER Insecure Ignore verification of Safeguard appliance SSL certificate. .PARAMETER AssetToSet An integer containing an asset ID or a string containing the asset name. .PARAMETER ParameterName A string containing the name of the custom script parameter to set. .PARAMETER ParameterValue A string containing the new value for the custom script parameter. .PARAMETER TaskName An optional string specifying the operation to target (e.g., TestConnection, CheckPassword, ChangePassword). If omitted, the value is applied to all operations that use the specified parameter name. .INPUTS None. .OUTPUTS JSON response from Safeguard Web API -- the updated asset object. .EXAMPLE Set-SafeguardCustomPlatformAssetParameter 263 "RequestTerminal" "False" .EXAMPLE Set-SafeguardCustomPlatformAssetParameter "MyLinuxAsset" "RequestTerminal" "False" -TaskName "CheckPassword" #> function Set-SafeguardCustomPlatformAssetParameter { [CmdletBinding()] Param( [Parameter(Mandatory=$false)] [string]$Appliance, [Parameter(Mandatory=$false)] [object]$AccessToken, [Parameter(Mandatory=$false)] [switch]$Insecure, [Parameter(Mandatory=$true,Position=0)] [object]$AssetToSet, [Parameter(Mandatory=$true,Position=1)] [string]$ParameterName, [Parameter(Mandatory=$true,Position=2)] [string]$ParameterValue, [Parameter(Mandatory=$false)] [string]$TaskName ) if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" } if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") } # Resolve asset Import-Module -Name "$PSScriptRoot\assets.psm1" -Scope Local $local:AssetId = (Resolve-SafeguardAssetId -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure $AssetToSet) # GET the full asset $local:AssetObj = (Invoke-SafeguardMethod -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure Core ` GET "Assets/$local:AssetId") if (-not $local:AssetObj.CustomScriptParameters -or $local:AssetObj.CustomScriptParameters.Count -eq 0) { throw "Asset '$AssetToSet' does not have any custom script parameters. " + ` "Ensure the asset uses a custom platform with a script that defines custom parameters." } # Find and update matching parameters $local:Updated = $false foreach ($local:Param in $local:AssetObj.CustomScriptParameters) { if ($local:Param.Name -eq $ParameterName) { if ($PSBoundParameters.ContainsKey("TaskName") -and $local:Param.TaskName -ne $TaskName) { continue } $local:Param.Value = $ParameterValue $local:Updated = $true } } if (-not $local:Updated) { if ($PSBoundParameters.ContainsKey("TaskName")) { throw "Unable to find custom script parameter '$ParameterName' for task '$TaskName' on asset '$AssetToSet'" } else { throw "Unable to find custom script parameter '$ParameterName' on asset '$AssetToSet'" } } Invoke-SafeguardMethod -AccessToken $AccessToken -Appliance $Appliance -Insecure:$Insecure Core ` PUT "Assets/$local:AssetId" -Body $local:AssetObj } |