New-Secret.ps1
Function New-Secret { <# .SYNOPSIS Create a new secret in secret server .DESCRIPTION Create a new secret in secret server This code only handles a pre-specified set of Secret templates defined in SecretType. Any fields not included in the parameters here are set to null .PARAMETER SecretType Secret Template to use .PARAMETER SecretName Secret Name .PARAMETER Domain For AD template, domain .PARAMETER Resource For Password template, resource .PARAMETER Server For SQL account template, Server .PARAMETER URL For Web template, URL .PARAMETER Machine For Windows template, Machine .PARAMETER Username Username .PARAMETER Password Password This takes a secure string, not a string .PARAMETER Notes Notes .PARAMETER FolderID Specific ID for the folder to create the secret within .PARAMETER FolderPath Folder path for the folder to create the secret within. Accepts '*' as wildcards, but must return a single folder. .PARAMETER Force If specified, suppress prompt for confirmation .PARAMETER WebServiceProxy An existing Web Service proxy to use. Defaults to $SecretServerConfig.Proxy .PARAMETER Uri Uri for your win auth web service. Defaults to $SecretServerConfig.Uri. Overridden by WebServiceProxy parameter .PARAMETER Token Token for your query. If you do not use Windows authentication, you must request a token. See Get-Help Get-SSToken .EXAMPLE New-Secret -SecretType 'Active Directory Account' -Domain Contoso.com -Username SQLServiceX -password $Credential.Password -notes "SQL Service account for SQLServerX\Instance" -FolderPath "*SQL Service" Create an active directory account for Contoso.com, user SQLServiceX, include notes that point to the SQL instance running it, specify a folder path matching SQL Service. .EXAMPLE $SecureString = Read-Host -AsSecureString -Prompt "Enter password" New-Secret -SecretType 'SQL Server Account' -Server ServerNameX -Username sa -Password $SecureString -FolderID 25 Create a secure string we will pass in for the password. Create a SQL account secret for the sa login on instance ServerNameX, put it in folder 25 (DBA). .FUNCTIONALITY Secret Server #> [cmdletbinding(DefaultParameterSetName = "AD", SupportsShouldProcess=$true, ConfirmImpact="Medium")] param( [parameter( Mandatory = $True )] [validateset("Active Directory Account", "SQL Server Account", "Web Password", "Windows Account", "Password")] [string]$SecretType, [parameter( ParameterSetName = "AD", Mandatory = $True )] [string]$Domain, [parameter( ParameterSetName = "PW", Mandatory = $True )] [string]$Resource, [parameter( ParameterSetName = "SQL", Mandatory = $True )] [string]$Server, [parameter( ParameterSetName = "WEB", Mandatory = $True )] [string]$URL, [parameter( ParameterSetName = "WIN", Mandatory = $True )] [string]$Machine, [parameter(ParameterSetName = "AD", Mandatory = $True )] [parameter(ParameterSetName = "PW", Mandatory = $False)] [parameter(ParameterSetName = "SQL", Mandatory = $True )] [parameter(ParameterSetName = "WEB", Mandatory = $True )] [parameter(ParameterSetName = "WIN", Mandatory = $True )] [string]$Username, [System.Security.SecureString]$Password = (Read-Host -AsSecureString -Prompt "Password for this secret:"), [string]$Notes, [int]$FolderID, [string]$FolderPath, [parameter(ParameterSetName = "PW", Mandatory = $True)] [parameter(ParameterSetName = "WEB", Mandatory = $True )] [parameter(ParameterSetName = "AD", Mandatory = $False )] [parameter(ParameterSetName = "SQL", Mandatory = $False )] [parameter(ParameterSetName = "WIN", Mandatory = $False )] [string]$SecretName, [switch]$Force, [string]$Uri = $SecretServerConfig.Uri, [System.Web.Services.Protocols.SoapHttpClientProtocol]$WebServiceProxy = $SecretServerConfig.Proxy, [string]$Token = $SecretServerConfig.Token ) $RejectAll = $false $ConfirmAll = $false $WebServiceProxy = Verify-SecretConnection -Proxy $WebServiceProxy -Token $Token Write-Verbose "PSBoundParameters:`n$($PSBoundParameters | Out-String)`nParameterSetName: $($PSCmdlet.ParameterSetName)" $InputHash = @{ Username = $Username Password = $Password Notes = $Notes } $SecretTypeParams = @{ AD = "Active Directory Account" SQL = "SQL Server Account" WEB = "Web Password" WIN = "Windows Account" PW = "Password" } if($SecretType -notlike $SecretTypeParams.$($PSCmdlet.ParameterSetName)) { Throw "Invalid secret type. For more information, run Get-Help New-Secret -Full" } #Verify the template and get the ID $Template = @( Get-SSTemplate -Name $SecretType ) if($Template.Count -ne 1) { Throw "Error finding template for $SecretType. Template results:`n$( $Template | Format-List -Property * -Force | Out-String )" } $SecretTypeId = $Template.ID #Verify the folder and get the ID $FolderHash = @{} if($FolderID) { $FolderHash.ID = $FolderID } if($FolderPath) { $FolderHash.FolderPath = $FolderPath } $Folder = @( Get-SSFolder @FolderHash ) if($Folder.Count -ne 1) { Throw "Error finding folder for $FolderHash. Folder results:`n$( $Folder | Format-List -Property * -Force | Out-String ). Valid folders: $(Get-SSFolder | ft -AutoSize | Out-String)" } $FolderId = $Folder.ID try { switch($PSCmdlet.ParameterSetName) { 'AD' { $InputHash.Domain = $Domain.ToLower() #Format is domain\user $ShortDomain = $InputHash.Domain.split(".")[0].ToLower() $SecretName = "$ShortDomain\$($InputHash.Username)" } 'PW' { $InputHash.Resource = $Resource } 'SQL' { $Server = $Server.ToLower() #format is instance::user. We use :: as instances may have a \ and would look odd. $InputHash.Server = $Server $SecretName = "$Server`::$($Username.tolower())" } 'WEB' { $InputHash.URL = $URL } 'WIN' { $Machine = $Machine.ToLower() $InputHash.Machine = $Machine #Format is machine\user $SecretName = "$Machine\$UserName" } } } catch { Throw "Error creating InputHash: $_" } #We control the order of fields, ensure all are present, by retrieving them and pulling user specified values from fields that exist. #TODO - Down the road we can provide a parameter for some sort of hash that allows ad hoc user specified fields, use this same methodology to ensure they are correct. $Fields = $Template | Get-SSTemplateField -erroraction stop $VerboseString = "InputHash:`n$($InputHash | Out-String)`n`nFields:`n$($Fields.DisplayName | Out-String)`nSecretTypeId: $SecretTypeId`nSecretTemplateName: $($SecretTypeParams.($PSCmdlet.ParameterSetName))`nSecretName: $SecretName`nFolderPath: $($Folder.FolderPath)" $FieldValues = Foreach($FieldName in $Fields.DisplayName) { if($FieldName -eq "Password") { try { Convert-SecStrToStr -secstr ($InputHash.$FieldName) -ErrorAction stop } catch { Throw "$_" } } else { $InputHash.$FieldName } } #We have everything, add the secret if($PSCmdlet.ShouldProcess( "Added the Secret $VerboseString", "Add the Secret $VerboseString?", "Adding Secret" )) { if($Force -Or $PSCmdlet.ShouldContinue("Are you REALLY sure you want to add the secret $VerboseString ?", "Adding $VerboseString", [ref]$ConfirmAll, [ref]$RejectAll)) { try { $Output = $WebServiceProxy.AddSecret($SecretTypeId, $SecretName, $Fields.Id, $FieldValues, $FolderId) if($Output.Secret) { $Output.Secret } if($Output.Error) { Throw "Error adding secret: $($Output.Error | Out-string)" } } catch { Throw "Error adding secret: $_" } } } } |