Users.psm1




<#
.SYNOPSIS
    The get users operation will retrieve a list of users from your company.
.DESCRIPTION
    The get users operation will retrieve a list of users from your company. This can be either all users, or users filtered by enabled / disabled.
.PARAMETER Userame
    Specifies the username of a user to retrieve, can be specified as an array of strings to retrieve multiple users
.PARAMETER UserGuid
    Specifies the Guid of a user to retrieve, can be specified as an array of Guids to retrieve multiple users
.PARAMETER UserType
    Specifies the type of user to retrieve, can be enabled, disabled or All
.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-HidUser
    Returns all the HidUsers in the tenant
.EXAMPLE
    Get-HidUser -UserType Disabled
    Returns all Disabled useraccounts in the tenant
.EXAMPLE
    Get-HidUser -Username user@testdomain.com
    Returns only the user with the specified username
.INPUTS
    
.OUTPUTS
    
#>

function Get-HidUser {
    [CmdletBinding(DefaultParameterSetName = 'guid',PositionalBinding = $false)]
    [Alias()]
    [OutputType([String])]
    Param ( 
        # the name of an existing variable
        [Parameter(Mandatory = $false,
        ValueFromPipeline = $true,
        ValueFromPipelineByPropertyName = $true,
        ParameterSetName = "guid")]
        [ValidateNotNullOrEmpty()]
        [guid[]]$UserGuid, 
    
        # the name of an existing variable
        [Parameter(Mandatory = $false,
        ValueFromPipeline = $true,
        ValueFromPipelineByPropertyName = $true,
        ParameterSetName = "Name")]
        [ValidateNotNullOrEmpty()]
        [string[]]$Username,
        
        [Parameter(Mandatory=$false,
        ValueFromPipeline=$false,
        ParameterSetName = "allusers")]
        [ValidateSet('Enabled','Disabled','All')]
        [string]$UserType = 'All',

        # 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
    )
    
    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)
        }
        elseif ($Global:HelloIdConnection.ApiCredentials) {
            Write-Verbose -Message "Using Global connectioninfo and credentials from Connect-HelloId "
            $Cred = $Global:HelloIdConnection.ApiCredentials
            $CompanyName = $Global:HelloIdConnection.CompanyName
        }
        else {            
            throw "Error finding connectioninfo. Connect using Connect-HelloId, or specifie CompanyName, ApiKey and ApiSecret"
        }

        #Headers
        $headers = @{
            "Content-Type" = "application/json"
        }
        
        #Variables
        [array]$resultArray = @()
        $take = 100


    } #End begin
    
    process {        

        if ($PSBoundParameters.ContainsKey("UserGuid")){            
            foreach ($guid in $UserGuid){
                $URI = "https://$CompanyName.helloid.com/api/v1/users/$guid"
                $output = Invoke-RestMethod -Uri $URI -Method "GET" -Headers $headers -Credential $Cred -UseBasicParsing               
                $output
            }

        }
        elseif ($PSBoundParameters.ContainsKey("Username")) {
            foreach ($user in $Username){
                $URI = "https://$CompanyName.helloid.com/api/v1/users/$user"
                $output = Invoke-RestMethod -Uri $URI -Method "GET" -Headers $headers -Credential $Cred -UseBasicParsing
                $output
            }
        }        
        else {

            do {
                
                switch($UserType)
                {
                    "Enabled"
                    {
                        $URI = "https://$CompanyName.helloid.com/api/v1/users?enabled=true" + "&skip=" + $resultArray.Count + "&take=$take"
                    }
                    "Disabled"
                    {
                        $URI = "https://$CompanyName.helloid.com/api/v1/users?enabled=false" + "&skip=" + $resultArray.Count + "&take=$take"
                    }
                    "All"
                    {
                        $URI = "https://$CompanyName.helloid.com/api/v1/users" + "?skip=" + $resultArray.Count + "&take=$take"
                    }
                }  
    
                $output = Invoke-RestMethod -Uri $URI -Method "GET" -Headers $headers -Credential $Cred -UseBasicParsing

                $resultArray += $output


            } while ($output.count -ge $take) #end do-while loop

            $resultArray            
        } #end else
    } #End process
    
    end {
        
    } #End end
} #End function




<#
.SYNOPSIS
    The get groups operation will retrieve a list of groups from your company.
.DESCRIPTION
    The get groups operation will retrieve a list of groups from your company. This can be either all groups, or groups filtered by groupmember.
.PARAMETER Name
    Specifies the name of an existing variable to retrieve, can be specified as an array of strings to retrieve multiple variables
.PARAMETER UserNames
    Usernames to add to the group
.PARAMETER UserGuids
    UserGuids to add to the group
.PARAMETER Enabled
    Is the new group enabled or disabled.
.PARAMETER Default
    Is the new group a default group
.PARAMETER QrEnabled
    Is QR-code generation for group members enabled
.PARAMETER ManagedByUserGuid
    The user Guid that will be considered the manager
.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
    
.EXAMPLE
    
.INPUTS
    
.OUTPUTS
    
#>

function New-HidUser {
    [CmdletBinding(PositionalBinding = $false)]
    [Alias()]
    [OutputType([String])]
    Param (
        
        # Username
        [Parameter(Mandatory= $true)]
        [ValidateNotNullOrEmpty()]
        [string]$UserName,

        # the name of the user to create
        [Parameter(Mandatory = $false)]
        [ValidateNotNullOrEmpty()]
        [string]$FirstName,
        
        # Last name
        [Parameter(Mandatory= $false)]
        [ValidateNotNullOrEmpty()]
        [string]$LastName,    
        
        # Last name
        [Parameter(Mandatory= $false)]
        [ValidateNotNullOrEmpty()]
        [securestring]$Password,
        
        # Is the new group enabled or disabled.
        [Parameter(Mandatory= $false)]
        [ValidateNotNullOrEmpty()]
        [bool]$Enabled = $true,
        
        # is the new group a default group
        [Parameter(Mandatory= $false)]
        [ValidateNotNullOrEmpty()]
        [bool]$MustChangePassword = $false,

        # is the new group a default group
        [Parameter(Mandatory= $false)]
        [ValidateNotNullOrEmpty()]
        [ValidateSet("Local","AD","IDP")]
        [string]$Source = "Local",
        
        # is QR-code generation for group members enabled
        [Parameter(Mandatory= $false)]
        [ValidateNotNullOrEmpty()]
        [string]$ContactEmail,
        
        # UserGuids to add to the group
        [Parameter(Mandatory= $false)]
        [ValidateNotNullOrEmpty()]
        [hashtable]$UserAttributes,

        # 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
    )
    
    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)
        }
        elseif ($Global:HelloIdConnection.ApiCredentials) {
            Write-Verbose -Message "Using Global connectioninfo and credentials from Connect-HelloId "
            $Cred = $Global:HelloIdConnection.ApiCredentials
            $CompanyName = $Global:HelloIdConnection.CompanyName
        }
        else {            
            throw "Error finding connectioninfo. Connect using Connect-HelloId, or specifie CompanyName, ApiKey and ApiSecret"
        }

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


        #Variables
        if ($PSBoundParameters.ContainsKey("UserAttributes")) {
            $JsonUserAttributes = ConvertTo-Json $UserAttributes -Depth 15
        }
        if ($PSBoundParameters.ContainsKey("Password")) {
            $BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Password)
            $UserPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
        }

    } #End begin
    
    process {
        
        $sbBody = [System.Text.StringBuilder]::new()
        $null = $SbBody.AppendLine("{") 
        if ($PSBoundParameters.ContainsKey("FirstName")) { $null = $SbBody.AppendLine("`"firstName`": `"$FirstName`",") }
        if ($PSBoundParameters.ContainsKey("LastName")) { $null = $SbBody.AppendLine("`"lastName`": `"$LastName`",") }
        if ($PSBoundParameters.ContainsKey("Password")) { $null = $SbBody.AppendLine("`"password`": `"$UserPassword`",") } 
        $null = $SbBody.AppendLine("`"isEnabled`": $(($Enabled).ToString().ToLower()),")
        $null = $SbBody.AppendLine("`"mustChangePassword`": $(($MustChangePassword).ToString().ToLower()),")
        $null = $SbBody.AppendLine("`"source`": `"$Source`",")
        if ($PSBoundParameters.ContainsKey("ContactEmail")) { $null = $SbBody.AppendLine("`"contactEmail`": `"$ContactEmail`",") }
        if ($PSBoundParameters.ContainsKey("UserAttributes")) { $null = $SbBody.AppendLine("`"userAttributes`": $JsonUserAttributes,") }       
        $null = $SbBody.AppendLine("`"userName`": `"$UserName`"")
        $null = $SbBody.AppendLine("}") 
        $URI = "https://$CompanyName.helloid.com/api/v1/users"
        Write-Debug "Body is:`n $($sbBody.ToString())"
        $output = Invoke-RestMethod -Uri $URI -Method "POST" -Headers $headers -Credential $Cred -UseBasicParsing -Body $sbBody.ToString()
        $output
        
    } #End process
    
    end {
        
    } #End end
} #End function






<#
.SYNOPSIS
    Removes a User from HelloId
.DESCRIPTION
    Removes a user based on the guid or username
.PARAMETER UserGuid
    Specifies the Guid from the user to remove, can be specified as an array to remove multiple
.PARAMETER UserName
    Specifies the Username from the user to remove, can be specified as an array to remove multiple
.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-HidUser -UserGuid "c31fd53a-b346-4bb4-9a67-f9406d3968db"

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

function Remove-HidUser {
    [CmdletBinding(DefaultParameterSetName = 'guid',
        PositionalBinding = $false)]
    [Alias()]
    [OutputType([String])]
    Param (
        # the GUID of an existing User
        [Parameter(Mandatory = $true,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            ParameterSetName = "guid")]
        [alias("Guid")]
        [ValidateNotNullOrEmpty()]
        [guid[]]$UserGuid,
        
        # the username of an existing User
        [Parameter(Mandatory = $true,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            ParameterSetName = "username")]
        [ValidateNotNullOrEmpty()]
        [string[]]$UserName,
        
        # 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
    )
    
    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)
        }
        elseif ($Global:HelloIdConnection.ApiCredentials) {
            Write-Verbose -Message "Using Global connectioninfo and credentials from Connect-HelloId "
            $Cred = $Global:HelloIdConnection.ApiCredentials
            $CompanyName = $Global:HelloIdConnection.CompanyName
        }
        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("UserGuid")){
            foreach ($guid in $UserGuid){
                #Uri
                $URI = "https://$CompanyName.helloid.com/api/v1/users/$guid"        
                Invoke-RestMethod -Uri $URI -Method "DELETE" -Headers $headers -Credential $Cred -UseBasicParsing        
            } #end foreach
        } #End If UserGuild
        if ($PSBoundParameters.ContainsKey("UserName")){
            foreach ($user in $UserName){
                #Uri
                $URI = "https://$CompanyName.helloid.com/api/v1/users/$user"        
                Invoke-RestMethod -Uri $URI -Method "DELETE" -Headers $headers -Credential $Cred -UseBasicParsing        
            } #end foreach
        } #End If UserGuild
    } #End process
    
    end {
    } #End end
} #End function






<#
.SYNOPSIS
    Updates an helloid user
.DESCRIPTION
    Updates an existing user if the passed identifier matches an existing user.
.PARAMETER UserGuid
    The GUID of the user to update
.PARAMETER UserName
    The username of the user to update
.PARAMETER FirstName
    The new firstname of the user (optional)
.PARAMETER LastName
    The new lastname of the user (optional)
.PARAMETER Password
    The new Password of the user, needs to be a securestring (optional)
.PARAMETER Enabled
    Enable or disable the user (optional)
.PARAMETER Locked
    Lock the user (optional)
.PARAMETER ResetMFA
    Reset MFA options for the user (optional)
.PARAMETER MustChangePassword
    User must reset password on next login (optional)
.PARAMETER ContactEmail
    The new Contactemail of the user (optional)
.PARAMETER UserAttributes
    Custom hashtable with a set of attributes to set for the user. This will remove already present attributes (optional)
.PARAMETER NewUserName
    The new username of the user. This will change the username and signin name for the user (optional)
.PARAMETER ImmutableId
    The new ImmutableId of the user. This will change the ImmutableId that is used by AD & AzureAD Sync engines
.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
    $hashUserAttributes = @{
        customatt = "123"
        phone = "1234567890"
    }
    Set-HidUser -UserGuid $user.UserGUID -NewUserName "newuser@domain.local" -ImmutableId "customId" -FirstName "newuser" -UserAttributes $hashUserAttributes -ContactEmail email@domain.com

.EXAMPLE
    Get-HidUser -Username "Username@domain.com" | Set-HidUser -ContactEmail newmail@domain.com
.INPUTS
    Inputs to this cmdlet (if any)
.OUTPUTS
    Output from this cmdlet (if any)
#>

function Set-HidUser {
    [CmdletBinding(DefaultParameterSetName = 'guid',
        PositionalBinding = $false)]
    [Alias()]
    [OutputType([String])]
    Param (
        # Optional, the GUID of an existing dynamic form
        [Parameter(Mandatory = $true,
            ParameterSetName = "guid",
            Position = 0,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            ValueFromRemainingArguments = $false)]
        [ValidateNotNullOrEmpty()]
        [ValidatePattern("^(\{){0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1}$")] #Matches a GUID
        [string[]]$UserGuid,

        # name of the form
        [Parameter(Mandatory= $true,
            ParameterSetName = "username",
            Position = 0,
            ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string[]]$UserName,

        # firstname
        [Parameter(Mandatory= $false)]
        [ValidateNotNullOrEmpty()]
        [string]$FirstName,

        # lastname
        [Parameter(Mandatory= $false)]
        [ValidateNotNullOrEmpty()]
        [string]$LastName,

        # new password for user
        [Parameter(Mandatory= $false)]
        [ValidateNotNullOrEmpty()]
        [securestring]$Password,
        
        # isEnabled
        [Parameter(Mandatory= $false)]
        [ValidateNotNullOrEmpty()]
        [bool]$Enabled = $true,

        # isLocked
        [Parameter(Mandatory= $false)]
        [ValidateNotNullOrEmpty()]
        [bool]$Locked = $false,

        # Reset MFA
        [Parameter(Mandatory= $false)]
        [ValidateNotNullOrEmpty()]
        [bool]$ResetMFA = $false,

        # Reset MFA
        [Parameter(Mandatory= $false)]
        [ValidateNotNullOrEmpty()]
        [bool]$MustChangePassword = $false,

        # contactEmail
        [Parameter(Mandatory= $false)]
        [ValidateNotNullOrEmpty()]
        [string]$ContactEmail,

        #Hashtable of user attributes
        [Parameter(Mandatory= $false)]
        [ValidateNotNullOrEmpty()]
        [hashtable]$UserAttributes,

        #New Username of user
        [Parameter(Mandatory= $false)]
        [ValidateNotNullOrEmpty()]
        [string]$NewUserName,

        #New ImmutableId of user
        [Parameter(Mandatory= $false)]
        [ValidateNotNullOrEmpty()]
        [string]$ImmutableId,

        # 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
    )
    
    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)
        }
        elseif ($Global:HelloIdConnection.ApiCredentials) {
            Write-Verbose -Message "Using Global connectioninfo and credentials from Connect-HelloId "
            $Cred = $Global:HelloIdConnection.ApiCredentials
            $CompanyName = $Global:HelloIdConnection.CompanyName
        }
        else {            
            throw "Error finding connectioninfo. Connect using Connect-HelloId, or specifie CompanyName, ApiKey and ApiSecret"
        }        

        #Headers
        $headers = @{
            "Content-Type" = "application/json"
        }
        
        
    } #End begin
    
    process {        
        #UserObj
        $NewUserObj = [PSCustomObject]@{}
        
        if ($PSBoundParameters.ContainsKey("UserGuid")) {
            $URI = "https://$CompanyName.helloid.com/api/v1/users/$UserGuid"
        }
        else {
            $URI = "https://$CompanyName.helloid.com/api/v1/users/$UserName"
        }

        if ($PSBoundParameters.ContainsKey("FirstName")){ $NewUserObj | Add-Member -NotePropertyName "firstName" -NotePropertyValue $FirstName }
        if ($PSBoundParameters.ContainsKey("LastName")){ $NewUserObj | Add-Member -NotePropertyName "lastName" -NotePropertyValue $LastName }
        if ($PSBoundParameters.ContainsKey("Password")){ $NewUserObj | Add-Member -NotePropertyName "password" -NotePropertyValue ((New-Object PSCredential "user",$Password).GetNetworkCredential().Password) }
        if ($PSBoundParameters.ContainsKey("Enabled")){ $NewUserObj | Add-Member -NotePropertyName "isEnabled" -NotePropertyValue $Enabled }
        if ($PSBoundParameters.ContainsKey("Locked")){ $NewUserObj | Add-Member -NotePropertyName "isLocked" -NotePropertyValue $Locked }
        if ($PSBoundParameters.ContainsKey("Locked")){ $NewUserObj | Add-Member -NotePropertyName "isLocked" -NotePropertyValue $Locked }
        if ($PSBoundParameters.ContainsKey("MustChangePassword")){ $NewUserObj | Add-Member -NotePropertyName "mustChangePassword" -NotePropertyValue $MustChangePassword }
        if ($PSBoundParameters.ContainsKey("ContactEmail")){ $NewUserObj | Add-Member -NotePropertyName "contactEmail" -NotePropertyValue $ContactEmail }
        if ($PSBoundParameters.ContainsKey("UserAttributes")){ $NewUserObj | Add-Member -NotePropertyName "userAttributes" -NotePropertyValue $UserAttributes }
        if (($PSBoundParameters.ContainsKey("NewUserName")) -OR ($PSBoundParameters.ContainsKey("ImmutableId"))){ 
            $IdentifierObj = @{}
            if ($PSBoundParameters.ContainsKey("NewUserName")){
                $IdentifierObj.Add("UserName",$NewUserName) | Out-Null
            }
            if ($PSBoundParameters.ContainsKey("ImmutableId")){
                $IdentifierObj.Add("ImmutableId",$ImmutableId) | Out-Null
            }
            $NewUserObj | Add-Member -NotePropertyName "IdentifierObject" -NotePropertyValue $IdentifierObj
        }
        
        
        $JsonUserObj = ConvertTo-Json -InputObject $NewUserObj -Depth 10

       

        Write-Debug -Message "Body is: `n$JsonUserObj"

        Invoke-RestMethod -Uri $URI -Method "PUT" -Headers $headers -Body $JsonUserObj -Credential $Cred -UseBasicParsing

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