Public/Add-VerkadaAccessUser.ps1
function Add-VerkadaAccessUser { <# .SYNOPSIS Adds an Access User in an organization .DESCRIPTION This function is used to add a Verkaka Access user or users to a Verkada Command Organization. As part of the user creation you can optionally add a badge and/or add the user to groups. The org_id and reqired tokens can be directly submitted as parameters, but is much easier to use Connect-Verkada to cache this information ahead of time and for subsequent commands. .LINK https://github.com/bepsoccer/verkadaModule/blob/master/docs/function-documentation/Add-VerkadaAccessUser.md .EXAMPLE Add-VerkadaAccessUser -firstName 'New' -lastName 'User' This will add the access user with the name "New User". The org_id and tokens will be populated from the cached created by Connect-Verkada. .EXAMPLE Add-VerkadaAccessUser -firstName 'New' -lastName 'User' -org_id '7cd47706-f51b-4419-8675-3b9f0ce7c12d' -x_verkada_token 'a366ef47-2c20-4d35-a90a-10fd2aee113a' -x_verkada_auth 'auth-token-uuid-dscsdc' -usr 'a099bfe6-34ff-4976-9d53-ac68342d2b60' This will add the access user with the name "New User". The org_id and tokens are submitted as parameters in the call. .EXAMPLE Add-VerkadaAccessUser -firstName 'New' -lastName 'User' -email 'newUser@contoso.com' This will add the access user with the name "New User" and email newUser@contoso.com. The org_id and tokens will be populated from the cached created by Connect-Verkada. .EXAMPLE Add-VerkadaAccessUser -email 'newUser@contoso.com' This will add the access user with the email newUser@contoso.com. The org_id and tokens will be populated from the cached created by Connect-Verkada. .EXAMPLE Add-VerkadaAccessUser -firstName 'New' -lastName 'User' -email 'newUser@contoso.com -department 'sales' -departmentId 'US-Sales' -employeeId '12345' -employeeTitle 'The Closer' -companyName 'Contoso' This will add the access user with the name "New User" and email newUser@contoso.com in department defined as sales with departmnetId of US-Sales with the appropriate employeeID, Title, and Company. The org_id and tokens will be populated from the cached created by Connect-Verkada. .EXAMPLE Add-VerkadaAccessUser -firstName 'New' -lastName 'User' -email 'newUser@contoso.com' -cardType 'HID' -facilityCode 111 -cardNumber 55555 -pinCode '12345' This will add the access user with the name "New User" and email newUser@contoso.com with an HID badge 111-55555 and a pin code of 12345. The org_id and tokens will be populated from the cached created by Connect-Verkada. .EXAMPLE Add-VerkadaAccessUser -firstName 'New' -lastName 'User' -email 'newUser@contoso.com' -cardType 'HID' -facilityCode 111 -cardNumber 55555 -groupId 'df76sd-dsc-group1','dsf987-daf-group2' This will add the access user with the name "New User" and email newUser@contoso.com with an HID badge 111-55555 and in groups df76sd-dsc-group1 and dsf987-daf-group2. The org_id and tokens will be populated from the cached created by Connect-Verkada. #> [CmdletBinding(PositionalBinding = $true)] Param( #The UUID of the organization the user belongs to [Parameter(ValueFromPipelineByPropertyName = $true)] [ValidateNotNullOrEmpty()] [ValidatePattern('^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$')] [String]$org_id = $Global:verkadaConnection.org_id, #The email address of the user being added [Parameter(ValueFromPipelineByPropertyName = $true)] [String]$email, #The first name of the user being added [Parameter(ValueFromPipelineByPropertyName = $true)] [String]$firstName, #The last name of the user being added [Parameter(ValueFromPipelineByPropertyName = $true)] [String]$lastName, #The Verkada(CSRF) token of the user running the command [Parameter()] [ValidateNotNullOrEmpty()] [ValidatePattern('^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$')] [string]$x_verkada_token = $Global:verkadaConnection.csrfToken, #The Verkada Auth(session auth) token of the user running the command [Parameter()] [ValidateNotNullOrEmpty()] [string]$x_verkada_auth = $Global:verkadaConnection.userToken, #The phone number of the user being added [Parameter(ValueFromPipelineByPropertyName = $true)] [ValidatePattern("^\+\d{11}")] [String]$phone, #The role of the user being added. [Parameter(ValueFromPipelineByPropertyName = $true)] [ValidateSet('ORG_MEMBER','ADMIN')] [String]$role='ORG_MEMBER', #Start date/time of the user being added [Parameter(ValueFromPipelineByPropertyName = $true)] [datetime]$start, #End date/time of the user being added [Parameter(ValueFromPipelineByPropertyName = $true)] [datetime]$expiration, #Boolean on whether to send invite email to newly created user [Parameter(ValueFromPipelineByPropertyName = $true)] [bool]$sendInviteEmail=$false, #The card type of the card being added [Parameter(ValueFromPipelineByPropertyName = $true)] [String]$cardType, #The card number of the card being added (Mutually exclusive with CardHex) [Parameter(ValueFromPipelineByPropertyName = $true)] [String]$cardNumber, #The card Number Hex of the card being added (Mutually exclusive with Card Number) [Parameter(ValueFromPipelineByPropertyName = $true)] [String]$cardNumberHex, #The facility code of the card being added [Parameter(ValueFromPipelineByPropertyName = $true)] [String]$facilityCode, #The pin code being added [Parameter(ValueFromPipelineByPropertyName = $true)] [ValidatePattern('^\d{4,16}$')] [Alias('pin')] [String]$pinCode, #The UUID of the group or groups the user should be added to on creation [Parameter(ValueFromPipelineByPropertyName = $true)] [String[]]$groupId, #The name of the group or groups the user should be added to on creation(not currently implemented) [Parameter(ValueFromPipelineByPropertyName = $true)] [String[]]$groupName, #The employee ID of the user [Parameter(ValueFromPipelineByPropertyName = $true)] [String]$employeeId, #The title of the user [Parameter(ValueFromPipelineByPropertyName = $true)] [String]$employeeTitle, #The department of the user [Parameter(ValueFromPipelineByPropertyName = $true)] [String]$department, #The departmentId of the user [Parameter(ValueFromPipelineByPropertyName = $true)] [String]$departmentId, #The company name of the user [Parameter(ValueFromPipelineByPropertyName = $true)] [String]$companyName, #The UUID of the user account making the request [Parameter()] [ValidateNotNullOrEmpty()] [ValidatePattern('^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$')] [string]$usr = $Global:verkadaConnection.usr, #Number of threads allowed to multi-thread the task [Parameter()] [ValidateRange(1,20)] [int]$threads=4 ) Begin { #parameter validation if ([string]::IsNullOrEmpty($org_id)) {throw "org_id is missing but is required!"} if ([string]::IsNullOrEmpty($x_verkada_token)) {throw "x_verkada_token is missing but is required!"} if ([string]::IsNullOrEmpty($x_verkada_auth)) {throw "x_verkada_auth is missing but is required!"} $url = "https://vcerberus.command.verkada.com/users/create" $jobs = @() $vMod = Get-Module verkadaModule | Select-Object -ExpandProperty Path } #end begin Process { #decide which parameter set is presented for first/last name and email if ([string]::IsNullOrEmpty($firstName) -and [string]::IsNullOrEmpty($lastName) -and [string]::IsNullOrEmpty($email)){ Write-Warning "No user created since no email or name was presented. An email and/or First/Last Name are required to create a user." return } elseif ((!([string]::IsNullOrEmpty($firstName))) -and (!([string]::IsNullOrEmpty($lastName))) -and (!([string]::IsNullOrEmpty($email)))) { #write-host "$firstName $lastName $email are all present" -ForegroundColor Red } elseif ((!([string]::IsNullOrEmpty($email))) -and [string]::IsNullOrEmpty($firstName) -and [string]::IsNullOrEmpty($lastName)) { #write-host "$email is the only thing present" -ForegroundColor Red } elseif (([string]::IsNullOrEmpty($firstName) -or [string]::IsNullOrEmpty($lastName))) { Write-Warning "No user created since either the first or last name is missing. First and Last Name are required to create a user if one is specified." return } elseif ((!([string]::IsNullOrEmpty($firstName)) -and (!([string]::IsNullOrEmpty($lastName)))) -and [string]::IsNullOrEmpty($email)) { #write-host "$firstName $lastname were specified and no email" -ForegroundColor Red } #build the form parameters for the user creation $form_params = @{ "organizationId" = $org_id } if (!([string]::IsNullOrEmpty($email))){$form_params.email = $email} if (!([string]::IsNullOrEmpty($firstName))){$form_params.firstName = $firstName} if (!([string]::IsNullOrEmpty($lastName))){$form_params.lastName = $lastName} if (!([string]::IsNullOrEmpty($phone))){$form_params.phone = $phone} if (!([string]::IsNullOrEmpty($role))){$form_params.role = $role} if (!([string]::IsNullOrEmpty($start))){$form_params.start = ([DateTimeOffset]($start)).ToUnixTimeSeconds()} if (!([string]::IsNullOrEmpty($expiration))){$form_params.expiration = ([DateTimeOffset]($expiration)).ToUnixTimeSeconds()} if (!([string]::IsNullOrEmpty($sendInviteEmail))){$form_params.sendInviteEmail = $sendInviteEmail.ToString().ToLower()} #start a threadJob for each user addition $jobs += Start-ThreadJob -ThrottleLimit $threads -ScriptBlock { Import-Module $using:vMod #Add the user to Command #Write-Output "Add user $using:firstName $using:lastName $using:email" $res = @{} try { $output = Invoke-VerkadaFormCall $using:url $using:org_id $using:form_params -x_verkada_token $using:x_verkada_token -x_verkada_auth $using:x_verkada_auth $res.created = ((Get-Date -Date "01-01-1970") + ([System.TimeSpan]::FromSeconds(($output.users.created)))).ToLocalTime() $res.userId = $output.users.userId $res.firstName = $output.users.firstName $res.lastName = $output.users.lastName $res.email = $output.users.email $response = $res | ConvertTo-Json -Depth 100 | ConvertFrom-Json } catch [Microsoft.PowerShell.Commands.HttpResponseException] { $err = $_.ErrorDetails | ConvertFrom-Json $errorMes = $_ | Convertto-Json -WarningAction SilentlyContinue $err | Add-Member -NotePropertyName StatusCode -NotePropertyValue (($errorMes | ConvertFrom-Json -Depth 100 -WarningAction SilentlyContinue).Exception.Response.StatusCode) -Force $res.created = '0' $res.firstName = $using:firstName $res.lastName = $using:lastName $res.email = $using:email Write-Warning "$using:firstName $using:lastName $using:email was not created due to: $($err.StatusCode) - $($err.message)" $noUser = $true } catch { $_.Exception $noUser = $true } finally { $response = $res | ConvertTo-Json -Depth 100 | ConvertFrom-Json } if ($noUser){return} #Add badge to user if present if (!([string]::IsNullOrEmpty($using:cardType))){ #Write-Output "Add badge $using:cardType $using:cardNumber $using:cardNumberHex $using:facilityCode" #Write-Output "Need to verify cardnumber or cardnumberhex are present as well as other card error handling" if (([string]::IsNullOrEmpty($using:cardNumber)) -and ([string]::IsNullOrEmpty($using:cardNumberHex))){ #check to see if both cardnumber and cardnumberhex are exmpty Write-Warning "No card is being added to $using:firstName $using:lastName $using:email as both cardnumber and cardnumberhex are missing. One is required." $res.accessCards = '' } elseif ((!([string]::IsNullOrEmpty($using:cardNumber))) -and (!([string]::IsNullOrEmpty($using:cardNumberHex)))) { #check to see if both cardnumber and cardnumberhex are present Write-Warning "No card is being added to $using:firstName $using:lastName $using:email as a cardnumber and cardnumberhex were submitted. They are mutually exclusive." $res.accessCards = '' } else { $eval = "`$response | Add-VerkadaAccessBadgeToUser -org_id $using:org_id -x_verkada_token $using:x_verkada_token -x_verkada_auth $using:x_verkada_auth -cardType $using:cardType" if (!([string]::IsNullOrEmpty($using:cardNumber))){$eval +=" -cardNumber $using:cardNumber"} if (!([string]::IsNullOrEmpty($using:cardNumberHex))){$eval +=" -cardNumberHex $using:cardNumberHex"} if (!([string]::IsNullOrEmpty($using:facilityCode))){$eval +=" -facilityCode $using:facilityCode"} try { $output2 = invoke-expression $eval $res.accessCards = $output2.accessCards } catch { if ($_.Exception.Message -match '^\d{3}\s-\s.*') { Write-Warning "No card is being added to $using:firstName $using:lastName $using:email due to: $($_.Exception.Message)" } else { $_.Exception } $res.accessCards = '' } } } else {$res.accessCards = ''} #Add pin to user if present if (!([string]::IsNullOrEmpty($using:pinCode))){ try { $outputPin = $response | Add-VerkadaAccessUserPin -pinCode $using:pinCode -org_id $using:org_id -x_verkada_token $using:x_verkada_token -x_verkada_auth $using:x_verkada_auth $res.pinCode = $outputPin.code } catch { if ($_.Exception.Message -match '^\d{3}\s-\s.*') { Write-Warning "No pin is being added to $using:firstName $using:lastName $using:email due to: $($_.Exception.Message)" } else { $_.Exception } $res.pinCode = '' } } else {$res.pinCode = ''} #add user to group/s if present if (!([string]::IsNullOrEmpty($using:groupId))){ #validate group is proper UUID $res.groupIds = @() switch -Regex ($using:groupId) { '^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$' { #Write-Output "Adding $using:firstName $using:lastName to $_" try { $response | Add-VerkadaAccessUserToGroup -groupId $_ -org_id $using:org_id -x_verkada_token $using:x_verkada_token -x_verkada_auth $using:x_verkada_auth | Out-Null $res.groupIds += $_ } catch { Write-Warning "$using:firstName $using:lastName $using:email was not added to the groupID provided ($_) due to: $($_.Exception.Message)" } } default {Write-Warning "$using:firstName $using:lastName $using:email was not added to the groupID provided ($_) as it is not a valid UUID"} } } elseif (!([string]::IsNullOrEmpty($using:groupName))) { <# Action when this condition is true #> } #add employment deatils if present $employment = @{} $eval3 = "Set-VerkadaAccessUserEmployementDetail -org_id $using:org_id -usr $using:usr -x_verkada_token $using:x_verkada_token -x_verkada_auth $using:x_verkada_auth -userId $($response.userId)" if (!([string]::IsNullOrEmpty($using:employeeId))){$employment.employeeId = $using:employeeId; $eval3 +=" -employeeId `$using:employeeId"} if (!([string]::IsNullOrEmpty($using:employeeTitle))){$employment.employeeTitle = $using:employeeTitle; $eval3 +=" -employeeTitle `$using:employeeTitle"} if (!([string]::IsNullOrEmpty($using:department))){$employment.department = $using:department; $eval3 +=" -department `$using:department"} if (!([string]::IsNullOrEmpty($using:departmentId))){$employment.departmentId = $using:departmentId; $eval3 +=" -departmentId `$using:departmentId"} if (!([string]::IsNullOrEmpty($using:companyName))){$employment.companyName = $using:companyName; $eval3 +=" -companyName `$using:companyName"} #check tp see if any employment details are present if ($employment.Count){ try { $employment.userId = $response.userId $output3 = invoke-expression $eval3 $res.employeeId = $output3.employeeId $res.employeeTitle = $output3.employeeTitle $res.department = $output3.department $res.departmentId = $output3.departmentId $res.companyName = $output3.companyName } catch { if ($_.Exception.Message -match '^\d{3}\s-\s.*') { Write-Warning "No employment details were updated for $using:firstName $using:lastName $using:email due to: $($_.Exception.Message)" } else { $_.Exception } $res.employeeId = '' $res.employeeTitle = '' $res.department = '' $res.departmentId = '' $res.companyName = '' } } else { $res.employeeId = '' $res.employeeTitle = '' $res.department = '' $res.departmentId = '' $res.companyName = '' } #aggregated response output $response = $res | ConvertTo-Json -Depth 100 | ConvertFrom-Json $response } } #end process End { $jobs | Receive-Job -AutoRemoveJob -Wait -WarningVariable +w -ErrorVariable +e foreach ($line in $w){Write-Output "Warning: $line"} foreach ($line in $e){Write-Output "Error: $line"} Remove-Variable -Name w -ErrorAction SilentlyContinue Remove-Variable -Name e -ErrorAction SilentlyContinue } #end end } #end function |