public/Start-TNDeploy.ps1
function Start-TNDeploy { <# .SYNOPSIS Deploys tenable.sc .DESCRIPTION Deploys tenable.sc .PARAMETER ComputerName The network name or IP address of the tenable.sc server .PARAMETER NessusPort The port of the Nessus server. Defaults to 8834 which is the default port for Nessus. .PARAMETER ScPort The port of the tenable.sc server. Defaults to 443 which is the default port for tenable.sc. .PARAMETER AdministratorCredential The credential object (from Get-Credential) used to log into the target server. Specifies a user account that has permission to send the request .PARAMETER LicensePath .PARAMETER AcceptSelfSignedCert Accept self-signed certs .PARAMETER SecurityManagerCredential .PARAMETER Scanner The hostname of the scanner or scanners to add .PARAMETER ScannerCredential The username and password used to add the scanners .PARAMETER InitializeScanner Initialize the Nessus scanner with admin password, don't just connect .PARAMETER Organization The name of the organization .PARAMETER Repository The name or names of the repositories .PARAMETER ScanZone The name of the ScanZone. Defaults to "All Computers" .PARAMETER ScanCredentialHash .PARAMETER IpRange .PARAMETER PolicyFilePath .PARAMETER ScanFilePath .PARAMETER AuditFilePath .PARAMETER DashboardFilePath .PARAMETER AssetFilePath .PARAMETER ReportFilePath .PARAMETER FeedFilePath .PARAMETER PluginFilePath .PARAMETER EnableTelemetry .PARAMETER EnableException By default, when something goes wrong we try to catch it, interpret it and give you a friendly warning message. This avoids overwhelming you with 'sea of red' exceptions, but is inconvenient because it basically disables advanced scripting. Using this switch turns this 'nice by default' feature off and enables you to catch exceptions with your own try/catch. .EXAMPLE $admincred = Get-Credential admin $secmancred = Get-Credential secmancred $splat = @{ ComputerName = "securitycenter" AdministratorCredential = $admincred SecurityManagerCredential = $secmancred Organization = "Acme" Repository = "All Computers" ScanZone = "All Computers" IpRange = "192.168.0.0/24" PolicyFilePath = "C:\nessus\library\policy.nessus", ScanFilePath = "C:\nessus\library\scan.nessus","C:\nessus\library\scan2.nessus" } PS C:\> Start-TNDeploy -Verbose #> [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "")] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string[]]$ComputerName, [Parameter(ValueFromPipelineByPropertyName)] [int]$NessusPort = 8443, [Parameter(ValueFromPipelineByPropertyName)] [int]$ScPort = 443, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [psobject]$AdministratorCredential, [Parameter(ValueFromPipelineByPropertyName)] [ValidateScript( { Test-Path -Path $_ })] [string]$LicensePath, [Parameter(ValueFromPipelineByPropertyName)] [switch]$AcceptSelfSignedCert, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [psobject]$SecurityManagerCredential, [Parameter(ValueFromPipelineByPropertyName)] [string[]]$Scanner, [Parameter(ValueFromPipelineByPropertyName)] [psobject]$ScannerCredential, [Parameter(ValueFromPipelineByPropertyName)] [switch]$InitializeScanner, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string]$Organization, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string[]]$Repository, [Parameter(ValueFromPipelineByPropertyName)] [string]$ScanZone = "All Computers", [Parameter(ValueFromPipelineByPropertyName)] [object[]]$ScanCredentialHash, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string[]]$IpRange, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateScript( { Test-Path -Path $_ })] [string[]]$PolicyFilePath, [Parameter(ValueFromPipelineByPropertyName)] [ValidateScript( { Test-Path -Path $_ })] [string[]]$ScanFilePath, [Parameter(ValueFromPipelineByPropertyName)] [ValidateScript( { Test-Path -Path $_ })] [string[]]$AuditFilePath, [Parameter(ValueFromPipelineByPropertyName)] [ValidateScript( { Test-Path -Path $_ })] [string[]]$DashboardFilePath, [Parameter(ValueFromPipelineByPropertyName)] [ValidateScript( { Test-Path -Path $_ })] [string[]]$AssetFilePath, [Parameter(ValueFromPipelineByPropertyName)] [ValidateScript( { Test-Path -Path $_ })] [string[]]$ReportFilePath, [Parameter(ValueFromPipelineByPropertyName)] [ValidateScript( { Test-Path -Path $_ })] [string]$FeedFilePath, [Parameter(ValueFromPipelineByPropertyName)] [ValidateScript( { Test-Path -Path $_ })] [string]$PluginFilePath, [Parameter(ValueFromPipelineByPropertyName)] [switch]$EnableTelemetry, [Parameter(ValueFromPipelineByPropertyName)] [switch]$EnableException ) begin { $elapsed = [System.Diagnostics.Stopwatch]::StartNew() $started = Get-Date $PSDefaultParameterValues["*:EnableException"] = $true $servertype = "tenable.sc" if ($AcceptSelfSignedCert) { $PSDefaultParameterValues['*-TN*:AcceptSelfSignedCert'] = $true } } process { if ($PSBoundParameters.Scanner -and -not $PSBoundParameters.ScannerCredential) { Stop-PSFFunction -EnableException:$EnableException -Message "You must provide a ScannerCredential when specifying a Scanner" return } if ($PSBoundParameters.PolicyFilePath -and -not $PSBoundParameters.FeedFilePath) { Stop-PSFFunction -EnableException:$EnableException -Message "You must provide a FeedFilePath when specifying a PolicyFilePath. Not sure why, but no Policy File uploads work without an initial feed update." return } if ($PSBoundParameters.InitializeScanner -and -not $PSBoundParameters.ScannerCredential) { Stop-PSFFunction -EnableException:$EnableException -Message "You must provide a ScannerCredential when specifying a InitializeScanner" return } if ($AdministratorCredential -isnot [pscredential]) { $AdministratorCredential = Get-Credential $AdministratorCredential -Message "Enter the username and password for the administrator credential on the $servertype server" } if ($PSBoundParameters.ScannerCredential -and $ScannerCredential -isnot [pscredential]) { $ScannerCredential = Get-Credential $ScannerCredential -Message "Enter the administrator username and password for the Nessus scanner" } if ($SecurityManagerCredential -isnot [pscredential]) { $SecurityManagerCredential = Get-Credential $SecurityManagerCredential -Message "Enter the username and password for the Security Manager credential for the organization $Organization" } foreach ($computer in $ComputerName) { $stepCounter = 0 $output = @{ ComputerName = $computer ServerType = "tenable.sc" } if ($LicensePath) { try { Write-PSFMessage -Level Verbose -Message "Initializing $computer" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Initializing $computer" if ($InitializeScanner -and $ScannerCredential) { $splat = @{ ComputerName = $computer Credential = $ScannerCredential Type = "Nessus" ManagedScanner = $true EnableException = $true ErrorAction = "Stop" } $null = Initialize-TNServer @splat -Port $NessusPort } $splat = @{ ComputerName = $computer Credential = $AdministratorCredential LicensePath = $LicensePath Type = "tenable.sc" EnableException = $true ErrorAction = "Stop" } $null = Initialize-TNServer @splat -Port $ScPort $output["LicensePath"] = $LicensePath $output["Administrator"] = $AdministratorCredential.Username } catch { Stop-PSFFunction -ErrorRecord $_ -EnableException:$EnableException -Message "Initialization failed for $computer" -Continue } } # Connect as admin try { Write-PSFMessage -Level Verbose -Message "Connecting to $computer" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Connecting to $computer" $null = Connect-TNServer -ComputerName $computer -Credential $AdministratorCredential -Type tenable.sc -Port $ScPort } catch { Stop-PSFFunction -ErrorRecord $_ -EnableException:$EnableException -Message "Connect failed for $computer" -Continue } # Disable telemetry if (-not $EnableTelemetry) { $results = Disable-TNTelemetry $output["TelemetryEnabled"] = $results.TelemetryEnabled -eq $true } # Scanner Credentials if ($ScanCredentialHash) { Write-PSFMessage -Level Verbose -Message "Creating credentials on $computer" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Creating credentials on $computer" try { foreach ($scancred in $ScanCredentialHash) { if ($scancred -is [hashtable]) { $null = New-TNCredential @scancred } else { $splat = ConvertTo-Hashtable $scancred $null = New-TNCredential @splat } } } catch { Stop-PSFFunction -ErrorRecord $_ -EnableException:$EnableException -Message "Credential creation failed for $computer" -Continue } $output["ScanCredential"] = $ScanCredentialHash.Name } # Org try { Write-PSFMessage -Level Verbose -Message "Creating an organization on $computer" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Creating an organization on $computer" $null = New-TNOrganization -Name $Organization $output["Organization"] = $Organization } catch { Stop-PSFFunction -ErrorRecord $_ -EnableException:$EnableException -Message "Creation of organization failed for $computer" -Continue } # Repository try { Write-PSFMessage -Level Verbose -Message "Creating a repository on $computer" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Creating a repository on $computer" $null = New-TNRepository -Name $Repository -IpRange $IpRange $output["Repository"] = $Repository $output["IpRange"] = $IpRange } catch { Stop-PSFFunction -ErrorRecord $_ -EnableException:$EnableException -Message "Creation of repository failed for $computer" -Continue } # Add org to repository try { Write-PSFMessage -Level Verbose -Message "Adding organization $Organization to repository $Repository on $computer" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Adding organization $Organization to repository $Repository on $computer" $null = Set-TNRepositoryProperty -Name $Repository -Organization $Organization } catch { Stop-PSFFunction -ErrorRecord $_ -EnableException:$EnableException -Message "Creation of repository failed for $computer" -Continue } # Organization User try { Write-PSFMessage -Level Verbose -Message "Creating an organization user on $computer" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Creating an organization user on $computer" $null = New-TNOrganizationUser -Organization $Organization -Credential $SecurityManagerCredential $output["SecurityManager"] = $SecurityManagerCredential.UserName } catch { Stop-PSFFunction -ErrorRecord $_ -EnableException:$EnableException -Message "Creation of organization user $($SecurityManagerCredential.Username) failed for $computer" -Continue } # Scanner if ($Scanner) { if ($InitializeScanner) { Start-Sleep 3 } try { foreach ($scannername in $scanner) { Write-PSFMessage -Level Verbose -Message "Adding scanner $scannername" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Adding scanner $scannername" $splat = @{ ComputerName = $scannername Credential = $ScannerCredential } $null = Add-TNScanner @splat } $output["Scanner"] = $Scanner $output["ScannerCredential"] = $ScannerCredential.Username } catch { Stop-PSFFunction -ErrorRecord $_ -EnableException:$EnableException -Message "Failed to add scanners" -Continue } } # Scan Zone try { Write-PSFMessage -Level Verbose -Message "Creating scan zones on $computer" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Creating scan zones on $computer" $null = New-TNScanZone -Name $ScanZone -IPRange $IpRange -Description "All organization computers" $output["ScanZone"] = $ScanZone if ($PSBoundParameters.Scanner) { $null = Set-TNScanZoneProperty -Name $ScanZone -Scanner $Scanner } } catch { Stop-PSFFunction -ErrorRecord $_ -EnableException:$EnableException -Message "Creation of scan zone failed for $computer" -Continue } # Update Feed if ($FeedFilePath) { Write-PSFMessage -Level Verbose -Message "Updating feed on $computer" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Updating feed on $computer" try { $null = Update-TNPluginFeed -Type Feed -FilePath $FeedFilePath -Wait } catch { Stop-PSFFunction -ErrorRecord $_ -EnableException:$EnableException -Message "Feed update failed for $computer" -Continue } $output["FeedFilePath"] = $FeedFilePath } # Update active plugins if ($PluginFilePath) { Write-PSFMessage -Level Verbose -Message "Updating active plugins on $computer" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Updating active plugins on $computer" try { $null = Update-TNPluginFeed -Type ActivePlugin -FilePath $PluginFilePath -Wait } catch { Stop-PSFFunction -ErrorRecord $_ -EnableException:$EnableException -Message "Feed update failed for $computer" -Continue } $output["PluginFilePath"] = $PluginFilePath } # Import policy if ($PSBoundParameters.PolicyFilePath) { try { Write-PSFMessage -Level Verbose -Message "Importing policies from $PolicyFilePath on $computer" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Importing policies from $PolicyFilePath on $computer" $results = Import-TNPolicy -FilePath $PolicyFilePath -EnableException:$EnableException $output["ImportedPolicy"] = $results.Name } catch { Stop-PSFFunction -ErrorRecord $_ -EnableException:$EnableException -Message "Policy import failed for $computer" -Continue } } # Connect as security manager try { $null = Remove-TNSession -SessionId 0 Write-PSFMessage -Level Verbose -Message "Connecting to $computer as $($SecurityManagerCredential.Username)" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Connecting to $computer" $null = Connect-TNServer -ComputerName $computer -Credential $SecurityManagerCredential -Type $servertype -Port $ScPort } catch { Stop-PSFFunction -ErrorRecord $_ -EnableException:$EnableException -Message "Connect failed for $computer as $($SecurityManagerCredential.Username)" -Continue } # Report Attribute try { Write-PSFMessage -Level Verbose -Message "Creating DISA report attribute on $computer" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Creating DISA report attribute on $computer" $null = New-TNReportAttribute -Name DISA $output["ReportAttribute"] = "DISA" } catch { Stop-PSFFunction -ErrorRecord $_ -EnableException:$EnableException -Message "DISA report attribute creation failed for $computer" -Continue } # Import report if ($PSBoundParameters.ReportFilePath) { try { Write-PSFMessage -Level Verbose -Message "Importing reports from $ReportFilePath on $computer" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Importing reports from $ReportFilePath on $computer" $results = Import-TNReport -FilePath $ReportFilePath $output["ImportedReport"] = $results.Name } catch { Stop-PSFFunction -ErrorRecord $_ -EnableException:$EnableException -Message "Report import failed for $computer" -Continue } } # Import audits if ($PSBoundParameters.AuditFilePath) { try { Write-PSFMessage -Level Verbose -Message "Importing audits from $AuditFilePath on $computer" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Importing audits from $AuditFilePath on $computer" $results = Import-TNAudit -FilePath $AuditFilePath $output["ImportedAudit"] = $results.Name Write-PSFMessage -Level Verbose -Message "Converting audits to policies on $computer" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Converting audits to policies on $computer" $results = New-TNPolicy -Auto $output["AuditPolicy"] = $results.Name } catch { Stop-PSFFunction -ErrorRecord $_ -EnableException:$EnableException -Message "Converting audits to policies failed for $computer" -Continue } } # Import dashboard if ($PSBoundParameters.DashboardFilePath) { try { Write-PSFMessage -Level Verbose -Message "Importing dashboards from $DashboardFilePath on $computer" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Importing dashboards from $DashboardFilePath on $computer" $results = Import-TNDashboard -FilePath $DashboardFilePath $output["ImportedDashboard"] = $results.Name } catch { Stop-PSFFunction -ErrorRecord $_ -EnableException:$EnableException -Message "Dashboard import failed for $computer" -Continue } } # Import asset if ($PSBoundParameters.AssetFilePath) { try { Write-PSFMessage -Level Verbose -Message "Importing assets from $AssetFilePath on $computer" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Importing assets from $AssetFilePath on $computer" $results = Import-TNAsset -FilePath $AssetFilePath $output["ImportedAsset"] = $results.Name } catch { Stop-PSFFunction -ErrorRecord $_ -EnableException:$EnableException -Message "Asset import failed for $computer" -Continue } } # Auto Scans! if ($PSBoundParameters.PolicyFilePath -or $PSBoundParameters.AuditFilePath) { try { Write-PSFMessage -Level Verbose -Message "Creating scans on $computer" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Creating scans on $computer" $scans = New-TNScan -Auto -TargetIpRange $IpRange -ScanCredentialHash $ScanCredentialHash $output["Scans"] = $scans.Name } catch { Stop-PSFFunction -ErrorRecord $_ -EnableException:$EnableException -Message "Scan creation failed for $computer" -Continue } } if ($PSBoundParameters.ScanFilePath) { try { Write-PSFMessage -Level Verbose -Message "Importing scans on $computer" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Importing scans on $computer" $results = Import-TNScan -FilePath $ScanFilePath $output["ImportedScans"] = $results.Name foreach ($scanname in $results.Name) { if ($PSBoundParameters.ScanCredentialHash) { $null = Set-TNScanProperty -Name $scans.Name -ScanCredential $ScanCredentialHash.Name } if ($PSBoundParameters.Repository) { $null = Set-TNScanProperty -Name $scans.Name -Repository $Repository } if ($PSBoundParameters.IpRange) { $null = Set-TNScanProperty -Name $scans.Name -IpRange $IpRange } } } catch { Stop-PSFFunction -ErrorRecord $_ -EnableException:$EnableException -Message "Scan import failed for $computer" -Continue } } # Create ASR Report try { Write-PSFMessage -Level Verbose -Message "Creating DISA ASR report on $computer" Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Creating DISA ASR report on $computer" $null = New-TNDisaAsrReport -Name "DISA ASR" -Description "DISA Detailed Asset Summary Reporting" $output["DISADetailedASR"] = "DISA ASR" } catch { Stop-PSFFunction -ErrorRecord $_ -EnableException:$EnableException -Message "Policy import failed for $computer" -Continue } Write-Progress -Activity "Finished deploying $computer for $servertype" -Completed $output["Status"] = "Success" [pscustomobject]$output | ConvertFrom-TNRestResponse } } end { $totalTime = ($elapsed.Elapsed.toString().Split(".")[0]) Write-PSFMessage -Level Verbose -Message "Export started: $started" Write-PSFMessage -Level Verbose -Message "Export completed: $(Get-Date)" Write-PSFMessage -Level Verbose -Message "Total Elapsed time: $totalTime" } } |