This is a quick one, it’s been forever since I’ve posted here. After moving back to Autotask, there’s still a ton of things to automate. One of the things that was bugging me was the fact you can’t set the client portal to default. Well, here’s a script you can run periodically to enable all the users to have the simple version of the client portal.

There is a few places you might want to update. I use a filter for a specific customer category, so where your $companies variable is, you may want to change or remove this part:

{“op”:”eq”,”field”:”companyCategoryID”,”value”:”101″}

Here’s the script, currently only handles companies with 500 or less contacts, I’ll update this with a loop to get all the contacts as well.

Function New-SecurePassword {
    $Password = "!?@#$%^&*0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz".tochararray()
($Password | Get-Random -Count 10) -Join ''
}

$at_uri = $($env:at_uri)
$at_integrationcode = $($env:at_integrationcode)
$at_username = $($env:at_username)
$at_secret = $($env:at_secret)

###AT HEADERS###
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("ApiIntegrationcode", "$at_integrationcode")
$headers.Add("Content-Type", 'application/json')
$headers.Add("UserName", "$at_username")
$headers.Add("Secret", "$at_secret")

$companies = $(Invoke-RestMethod -uri $($at_uri + '/v1.0/Companies/query?search={"IncludeFields": ["id", "companyName","companyNumber","isActive"],"filter":[{"op":"eq","field":"companyCategoryID","value":"101"}]}') -Headers $headers -Method Get).items

foreach ($company in $companies | Select-Object -skip 3) { 
    $contacts = $(Invoke-RestMethod -uri $($at_uri + '/v1.0/Contacts/query?search={"IncludeFields": ["id", "firstName","lastName","isActive","emailAddress"],"filter":[{"op":"and","items":[{"op":"eq","field":"companyID","value":"' + $($company.id) + '"},{"op":"eq","field":"isActive","value":"true"}]}]}') -Headers $headers -Method Get).items
    $query = $null;
    $x = 0; $y = 0;
    $clientportal = @();
    do {
        foreach ($contact in $contacts) {
            if ($query) { 
                $query += ',{"op":"eq","field":"contactID","value":"' + $($contact.id) + '"}'
            }
            if (!$query) { 
                $query = '{"op":"eq","field":"contactID","value":"' + $($contact.id) + '"}'
            }
            $y++; $x++;
            if ($x -eq $contacts.Count) { $y = 100 }
            if ($y -eq 100) { 
                $postbody = '{"filter":[{"op":"or","items":[' + $query + ']}]}'
                $clientportal += $(Invoke-RestMethod -uri $($at_uri + '/v1.0/ClientPortalUsers/query') -Body $postbody -Headers $headers -Method Post).items
                $query = $null; $y = 0;
            }
        }
    }
    while ($x -lt $contacts.count)
    if ($clientportal.count -ne $contacts.count) { 
        write-host "Contacts: $($contacts.count)"
        write-host "Enabled: $($clientportal.count)"
        $missing = $null;
        $missing = $contacts.id | Where-Object { $_ -notin $clientportal.contactId }
        foreach ($miss in $missing) { 
            $contact = $null;
            $contact = $contacts | Where-Object { $miss -eq $_.id }
            write-host "$($contact.emailAddress)"
            $json = [PSObject]@{
                contactID            = $($contact.id)
                userName             = "$($contact.emailAddress)"
                securityLevel        = 1
                password             = "$(new-securepassword)"
                numberFormat         = 22
                dateFormat           = 1
                timeFormat           = 1
                isClientPortalActive = $true
            }
            $json = $json | ConvertTo-Json
            Start-Sleep -Milliseconds 10
            Invoke-RestMethod -uri $($at_uri + '/v1.0/ClientPortalUsers') -Method POST -Body $json -Headers $headers
        }
    }
}