DataSources.psm1




<#
.SYNOPSIS
    Retrieves an HelloId DataSource
.DESCRIPTION
    Get-HidDataSource will return one or more Datasources
.PARAMETER DataSourceGuid
    Specifies the Guid of an existing datasource to retrieve, can be specified as an array of strings to retrieve multiple variables
.PARAMETER Name
    Specifies the name of an existing datasource to retrieve, can be specified as an array of strings to retrieve multiple variables
.PARAMETER CompanyName
    The companyname that's used in the helloId URL to know which HelloID tenant to talk to. Required if not connected with Connect-HelloId.
.PARAMETER ApiKey
    The Apikey to use for the api call. Required if not connected with Connect-HelloId.
.PARAMETER ApiSecret
    The Apisecret belonging to the apikey, has to be a securestring. Required if not connected with Connect-HelloId.
.EXAMPLE
    Get-HidDataSource -CompanyName "MyCompany" -ApiKey "myapikey" -ApiSecret (ConvertTo-SecureString -AsPlainText -String "password" -Force)
    
    Returns all datasources
.EXAMPLE
    Get-HidDataSource

    Returns all datasources in the tenant
.EXAMPLE
    Get-HidDatasource -DataSourceGuid "812302af-c3db-4a66-c39d-08d7d4a10f72"
    
    Returns the datasource with guid 812302af-c3db-4a66-c39d-08d7d4a10f72
.EXAMPLE
    "AD-group-generate-table" | Get-HidDataSource

    Returns the datasource with name AD-group-generate-table. The name can be piped
.INPUTS
    You can pipe a string that contains the name to Get-HidDataSource
.OUTPUTS
    Returns an object for each datasource that it gets.
#>

function Get-HidDataSource {
    [CmdletBinding(DefaultParameterSetName = 'Name',PositionalBinding = $false)]
    [Alias()]
    [OutputType([String])]
    Param (
        # the GUID of an existing datasource
        [Parameter(Mandatory = $false,
            ValueFromPipelineByPropertyName = $true,
            ParameterSetName = "Guid")]
        [alias("Guid")]
        [ValidateNotNullOrEmpty()]
        [guid[]]$DataSourceGuid,
                
        # the name of an existing datasource
        [Parameter(Mandatory = $false,
        ValueFromPipeline = $true,
        ValueFromPipelineByPropertyName = $true,
        ParameterSetName = "Name")]
        [ValidateNotNullOrEmpty()]
        [string[]]$Name,

        # Company name used in the URL
        [Parameter(Mandatory= $false)]
        [ValidateNotNullOrEmpty()]
        [string]$CompanyName,
        
        # Api key
        [Parameter(Mandatory= $false)]
        [ValidateNotNullOrEmpty()]
        [string]$ApiKey,

        # Api secret
        [Parameter(Mandatory= $false)]
        [ValidateNotNullOrEmpty()]
        [securestring]$ApiSecret,

        # For preview tenants
        [Parameter(Mandatory = $false)]
        [switch]$IsPreviewTenant
    )
    
    begin {

        if ($PSBoundParameters.ContainsKey("CompanyName") -AND $PSBoundParameters.ContainsKey("ApiKey") -AND $PSBoundParameters.ContainsKey("ApiSecret") ){
            Write-Verbose -Message "Using connectioninfo and credentials from parameter"
            #Create credential object for authentication
            $Cred = New-Object System.Management.Automation.PSCredential ($ApiKey, $ApiSecret)
            if ($IsPreviewTenant){
                $BaseUrl = "https://$CompanyName.preview-helloid.com"
            }
            else {
                $BaseUrl = "https://$CompanyName.helloid.com"
            }
        }
        elseif ($Global:HelloIdConnection.ApiCredentials) {
            Write-Verbose -Message "Using Global connectioninfo and credentials from Connect-HelloId "
            $Cred = $Global:HelloIdConnection.ApiCredentials
            $CompanyName = $Global:HelloIdConnection.CompanyName
            $BaseUrl = $Global:HelloIdConnection.BaseUrl
        }
        else {            
            throw "Error finding connectioninfo. Connect using Connect-HelloId, or specifie CompanyName, ApiKey and ApiSecret"
        }

        #Headers
        $headers = @{
            "Content-Type" = "application/json"
        }
        
    } #End begin
    
    process {        

        if ($PSBoundParameters.ContainsKey("DatasourceGuid")){            
            foreach ($guid in $DataSourceGuid){
                $URI = "$BaseUrl/api/v1/datasource/$guid"
                $output = Invoke-RestMethod -Uri $URI -Method "GET" -Headers $headers -Credential $Cred -UseBasicParsing               
                $output
            }

        }
        elseif ($PSBoundParameters.ContainsKey("Name")) {
            foreach ($item in $Name){
                $URI = "$BaseUrl/api/v1/datasource/named/$item"
                $output = Invoke-RestMethod -Uri $URI -Method "GET" -Headers $headers -Credential $Cred -UseBasicParsing
                $output
            }
        }
        else {
            $URI = "$BaseUrl/api/v1/datasource/all"
            $output = Invoke-RestMethod -Uri $URI -Method "GET" -Headers $headers -Credential $Cred -UseBasicParsing
            <#
            if ($output.psobject.Properties.name -contains "data"){
                $output = $output.data
            }
            #>

            return $output               
            
        }
        
        
    } #End process
    
    end {
        
    } #End end
} #End function




<#
.SYNOPSIS
    Creates or updates a datasource
.DESCRIPTION
    Creates a new record of a datasource if the DataSourceGUID is left empty. Updates an existing DataSource if the passed identifier guid matches an existing datasource.
.PARAMETER DataSourceGuid
    If specified it specifies the Guid of an existing datasource to update, if not specified it creates a new datasource
.PARAMETER Name
    Sets the name of the datasource to create or update
.PARAMETER Type
    Sets the Type of the datasource to create or update.
    2 is for Static DataSources
    3 is for Task DataSources
    4 is for Powershell datasources
.PARAMETER Model
    An array containing objects that each represent one of the Data source's output properties.
    Each objects requires the following properties:
    {Key} Name of this output property
    {Type} Type of this output property
.PARAMETER Value
    An array containing zero or more objects. It represents the records a Static Data source will return, Required for Static Data sources
.PARAMETER AutomationTaskGuid
    A guid referring to the Task associated with this Task Data Source
.PARAMETER Input
    An array containing objects that each represent a Data Source Input property. Each object requires the following properties:
    {Key} Name of this input property - Required
    {InputFieldType} Type of this input property. Either 1 (for an input property that can be configured for each form element that is linked to this Data source, also known as a Form input property) or 2 (for an input property that has a predefined value, also known as a Predefined input property) - Required
    {Options} Either 0 (for an input field that is not required) or 1 (for one that is) - Required
    {Description} The description that will show up when configuring a form field that uses this data source. Only relevant for Form input properties. Required for Form input properties
    {PredefinedValue} The predefined value of this input property. May contain HelloID language such as '{{requester.FirstName}}' Required for Predefined input properties
.PARAMETER CompanyName
    The companyname that's used in the helloId URL to know which HelloID tenant to talk to. Required if not connected with Connect-HelloId.
.PARAMETER ApiKey
    The Apikey to use for the api call. Required if not connected with Connect-HelloId.
.PARAMETER ApiSecret
    The Apisecret belonging to the apikey, has to be a securestring. Required if not connected with Connect-HelloId.
.EXAMPLE
    $ApiKey = "myapikey"
    $ApiSecret = ConvertTo-SecureString -AsPlainText -String "mypassword" -Force
    $CompanyName = "contoso"

    $parameterSplat = @{
    Companyname = $CompanyName
    ApiKey = $ApiKey
    ApiSecret = $ApiSecret
    }
    $sourceDS = Get-HidDatasource -DatasourceGuid "812302af-c3db-4a66-c39d-08d7d4a10f72" @ParameterSplat
    Set-HidDataSource -Name "testDS" -Type $sourceDS.type -Model $sourceDS.model -AutomationTaskGuid $sourceDS.automationTaskGUID @ParameterSplat

    Creates a new Task Datasource with name testDS based on the source datasource with the specified Guid
.EXAMPLE
    Get-HidDataSource -Name testDS | Set-HidDataSource -Name testDS2
    
    Changes the name from the datasource from testDS to testDS2

.INPUTS
    You can pipe that output from Get-DataSouce to Set-DataSource with all the changes
.OUTPUTS

#>

function Set-HidDataSource {
    [CmdletBinding(DefaultParameterSetName = 'taskdatasource',
        PositionalBinding = $false)]
    [Alias()]
    [OutputType([String])]
    Param (
        # Optional, the GUID of an existing datasource
        [Parameter(Mandatory = $false,
            Position = 0,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            ValueFromRemainingArguments = $false)]
        [ValidateNotNullOrEmpty()]
        [guid]$DataSourceGuid,

        # name of the datasource
        [Parameter(Mandatory= $true,
            ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string]$Name,

        # Either 2 (if it is a static Data source) or 3 (if it is a Task Data source) or 4 (if its a powershell datasource)
        [Parameter(Mandatory= $true,
            ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [ValidateSet(2,3,4)]
        [int]$Type,

        # An array containing objects that each represent one of the Data source's output properties
        [Parameter(Mandatory= $true,
            ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [array]$Model,
        
        # An array containing zero or more JSON objects. It represents the records a Static Data source will return, Required for Static Data sources
        [Parameter(Mandatory= $true,
            ParameterSetName = "staticdatasource",
            ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [array]$Value,

        # A guid referring to the Task associated with this Task Data Source, Required for Task Data sources
        [Parameter(Mandatory= $true,
            ParameterSetName = "taskdatasource",
            ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string]$AutomationTaskGuid,

        # An array containing objects that each represent a Data Source Input property, for Task Data sources only
        [Parameter(Mandatory= $false,
            ParameterSetName = "taskdatasource",
            ValueFromPipelineByPropertyName = $true)]
        [Parameter(Mandatory= $false, 
            ParameterSetName = "powershelldatasource")]
        [alias("Input")]
        [array]$DataSourceInput,

        # Powershell script, for PowerShell Data sources only
        [Parameter(Mandatory= $false,
        ParameterSetName = "powershelldatasource",
        ValueFromPipelineByPropertyName = $true)]
        [alias("PowerShellScript")]
        [string]$Script,

        # Company name used in the URL
        [Parameter(Mandatory= $false)]
        [ValidateNotNullOrEmpty()]
        [string]$CompanyName,
        
        # Api key
        [Parameter(Mandatory= $false)]
        [ValidateNotNullOrEmpty()]
        [string]$ApiKey,

        # Api secret
        [Parameter(Mandatory= $false)]
        [ValidateNotNullOrEmpty()]
        [securestring]$ApiSecret,

        # For preview tenants
        [Parameter(Mandatory = $false)]
        [switch]$IsPreviewTenant
    )
    
    begin {
        if ($PSBoundParameters.ContainsKey("CompanyName") -AND $PSBoundParameters.ContainsKey("ApiKey") -AND $PSBoundParameters.ContainsKey("ApiSecret") ){
            Write-Verbose -Message "Using connectioninfo and credentials from parameter"
            #Create credential object for authentication
            $Cred = New-Object System.Management.Automation.PSCredential ($ApiKey, $ApiSecret)
            if ($IsPreviewTenant){
                $BaseUrl = "https://$CompanyName.preview-helloid.com"
            }
            else {
                $BaseUrl = "https://$CompanyName.helloid.com"
            }
        }
        elseif ($Global:HelloIdConnection.ApiCredentials) {
            Write-Verbose -Message "Using Global connectioninfo and credentials from Connect-HelloId "
            $Cred = $Global:HelloIdConnection.ApiCredentials
            $CompanyName = $Global:HelloIdConnection.CompanyName
            $BaseUrl = $Global:HelloIdConnection.BaseUrl
        }
        else {            
            throw "Error finding connectioninfo. Connect using Connect-HelloId, or specifie CompanyName, ApiKey and ApiSecret"
        }

        
        $JsonModel = ConvertTo-Json $Model -Depth 15
        $JsonValue = ConvertTo-Json $Value -Depth 15
        $JsonInput = ConvertTo-Json $DataSourceInput -Depth 15
        #Headers
        $headers = @{
            "Content-Type" = "application/json"
        }

        #Uri
        $URI = "$BaseUrl/api/v1/datasource"
    } #End begin
    
    process {
        if ($Type -eq 2) { #static datasource

            $SbBody = [System.Text.StringBuilder]::new()
            $null = $SbBody.AppendLine("{")
            if ($PSBoundParameters.ContainsKey("DataSourceGuid")){ $null = $SbBody.AppendLine("`"dataSourceGUID`": `"$DataSourceGuid`"`,") }
            $null = $SbBody.AppendLine("`"type`": `"$Type`",")
            $null = $SbBody.AppendLine("`"name`": `"$Name`",")
            $null = $SbBody.AppendLine("`"model`": $JsonModel,")
            $null = $SbBody.AppendLine("`"value`": $JsonValue")
            $null = $SbBody.AppendLine("}")
            
        } #END if static datasource

        if ($Type -eq 3) { #task datasource

            $SbBody = [System.Text.StringBuilder]::new()
            $null = $SbBody.AppendLine("{")
            if ($PSBoundParameters.ContainsKey("DataSourceGuid")){ $null = $SbBody.AppendLine("`"dataSourceGUID`": `"$DataSourceGuid`"`,") }
            $null = $SbBody.AppendLine("`"type`": `"$Type`",")
            $null = $SbBody.AppendLine("`"name`": `"$Name`",")
            $null = $SbBody.AppendLine("`"model`": $JsonModel,")
            $null = $SbBody.AppendLine("`"automationTaskGUID`": `"$AutomationTaskGuid`",")
            $null = $SbBody.AppendLine("`"input`": $JsonInput")
            $null = $SbBody.AppendLine("}")
            
        } #END if task datasource

        if ($Type -eq 4){ # new Powershell datasource

            $SbBody = [System.Text.StringBuilder]::new()
            $null = $SbBody.AppendLine("{")
            if ($PSBoundParameters.ContainsKey("DataSourceGuid")){ $null = $SbBody.AppendLine("`"dataSourceGUID`": `"$DataSourceGuid`"`,") }
            $null = $SbBody.AppendLine("`"type`": `"$Type`",")
            $null = $SbBody.AppendLine("`"name`": `"$Name`",")
            $null = $SbBody.AppendLine("`"model`": $JsonModel,")
            if ($PSBoundParameters.ContainsKey("DataSourceInput")) { $null = $SbBody.AppendLine("`"input`": $JsonInput,") }
            $null = $SbBody.AppendLine("`"script`": `"$Script`"")
            $null = $SbBody.AppendLine("}")


        } #END if Powershell datasource

        Write-Debug "Invoking REST method"
        Write-Debug "Uri = $URI"
        Write-Debug "Headers = $headers"
        Write-Debug "body = $($SbBody.ToString())"
        Write-Debug "Credential = $Cred"
        Write-Verbose "Creating / Setting datasource with name: $Name"
        $output = Invoke-RestMethod -Uri $URI -Method "POST" -Headers $headers -Body $SbBody.ToString() -Credential $Cred -UseBasicParsing


    } #End process
    
    end {
        return $output
    } #End end
} #End function







<#
.SYNOPSIS
    Removes a Data Source
.DESCRIPTION
    Removes a Data Source based on the guid
.PARAMETER DataSourceGuid
    Specifies the Guid of an existing data source to remove, can be specified as an array of strings to remove multiple variables
.PARAMETER CompanyName
    The companyname that's used in the helloId URL to know which HelloID tenant to talk to. Required if not connected with Connect-HelloId.
.PARAMETER ApiKey
    The Apikey to use for the api call. Required if not connected with Connect-HelloId.
.PARAMETER ApiSecret
    The Apisecret belonging to the apikey, has to be a securestring. Required if not connected with Connect-HelloId.
.EXAMPLE
    Remove-HidDataSource -DataSourceGuid "c31fd53a-b346-4bb4-9a67-f9406d3968db"

    Removes the Data Source with the specified GUID
.INPUTS
    Inputs to this cmdlet (if any)
.OUTPUTS
    Output from this cmdlet (if any)
#>

function Remove-HidDataSource {
    [CmdletBinding(DefaultParameterSetName = 'Parameter Set 1',
        PositionalBinding = $false)]
    [Alias()]
    [OutputType([String])]
    Param (
        # the GUID of an existing Data Source
        [Parameter(Mandatory = $true,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true)]
        [alias("Guid")]
        [ValidateNotNullOrEmpty()]
        [guid[]]$DataSourceGuid,        
        
        # Company name used in the URL
        [Parameter(Mandatory= $false)]
        [ValidateNotNullOrEmpty()]
        [string]$CompanyName,
        
        # Api key
        [Parameter(Mandatory= $false)]
        [ValidateNotNullOrEmpty()]
        [string]$ApiKey,

        # Api secret
        [Parameter(Mandatory= $false)]
        [ValidateNotNullOrEmpty()]
        [securestring]$ApiSecret,

        # For preview tenants
        [Parameter(Mandatory = $false)]
        [switch]$IsPreviewTenant
    )
    
    begin {
        if ($PSBoundParameters.ContainsKey("CompanyName") -AND $PSBoundParameters.ContainsKey("ApiKey") -AND $PSBoundParameters.ContainsKey("ApiSecret") ){
            Write-Verbose -Message "Using connectioninfo and credentials from parameter"
            #Create credential object for authentication
            $Cred = New-Object System.Management.Automation.PSCredential ($ApiKey, $ApiSecret)
            if ($IsPreviewTenant){
                $BaseUrl = "https://$CompanyName.preview-helloid.com"
            }
            else {
                $BaseUrl = "https://$CompanyName.helloid.com"
            }
        }
        elseif ($Global:HelloIdConnection.ApiCredentials) {
            Write-Verbose -Message "Using Global connectioninfo and credentials from Connect-HelloId "
            $Cred = $Global:HelloIdConnection.ApiCredentials
            $CompanyName = $Global:HelloIdConnection.CompanyName
            $BaseUrl = $Global:HelloIdConnection.BaseUrl
        }
        else {            
            throw "Error finding connectioninfo. Connect using Connect-HelloId, or specifie CompanyName, ApiKey and ApiSecret"
        }

        #Headers
        $headers = @{
            "Content-Type" = "application/json"
        }
        
        
    } #End begin
    
    process {        

        foreach ($guid in $DataSourceGuid){
        #Uri
        $URI = "$BaseUrl/api/v1/datasource/$guid"        
        Invoke-RestMethod -Uri $URI -Method "DELETE" -Headers $headers -Credential $Cred -UseBasicParsing        
        } #end foreach

    } #End process
    
    end {
    } #End end
} #End function