Deleting inactive Sharefile invites
Posted
File collaboration external to a firm is always a delicate balance. Too strict a set of IT rules and staff resort to email attachments and shadow IT. Too loose and you have a bunch of external users with access to various parts of your SaaS stack. Either way, there is a clear business need and many vendors strive to meet it, from pure plays like Dropbox down to guest user features in SharePoint.
Sharefile can be a good solution in this space: user driven guest enrollment without the guests having any possible access to any other system.
One of the challenges with any guest access though, is that a certain percentage of guest invites are never accepted. From a data and cyber security hygiene perspective it’s important that these unused invites expire.
Unfortunately that doesn’t seem to be a native feature of Sharefile. Happily, the following script works nicely to do the cleanup. Run from an Azure Automation Runbook (or similar) on a schedule and you’re good to go.
I hope you find it useful.
# Retrieve all clients from Sharefile, execute a delete for any who haven't
# accepted their invite within 60 days
$sfSecret = Get-AutomationVariable -Name "ShareFileSecret"
$sfID = Get-AutomationVariable -Name "ShareFileClientID"
$sfCredentials = Get-AutomationPSCredential -Name 'Sharefile Service Account'
$Url = "https://XXXX.sharefile.com/oauth/token"
$Body = @{
'grant_type'='password';
'client_id'=$sfID;
'client_secret'=$sfSecret;
'username'=$sfCredentials.UserName
'password'=$sfCredentials.GetNetworkCredential().Password
}
$result = Invoke-RestMethod -Method 'GET' -Body $body `
-Headers @{"Content-Type"="application/x-www-form-urlencoded"} -Uri $url
$headerParams = @{'Authorization'="Bearer $($result.access_token)"}
$filter = 'CreatedDate lt date('+(get-date).AddDays(-60).toString('yyyy-MM-dd')+`
') and IsConfirmed eq False'
$clientURI = 'https://XXXX.sf-api.com/sf/v3/Accounts/Clients'
$deleteURL = 'https://XXXX.sf-api.com/sf/v3/Users/Clients/BulkDelete'
$clientBody = @{
'`$select'='Name,IsConfirmed,CreatedDate,Id,Email';
'`$filter'=$filter
}
$users = Invoke-RestMethod -Header $headerParams -Method 'GET' -Body $clientBody `
-Uri $clientURI
Write-Output "Found $($users.value.count) clients"
$toDelete = @()
$deleteCount = 0
$cutoff = (get-date).AddDays(-60)
foreach($user in $users.value){
# make sure
if(!$user.isConfirmed -and [DateTime]($user.CreatedDate) -lt $cutoff){
$toDelete +=$user.id
$deleteCount++
Write-Output "Will delete $($user.email), ($($user.id)) "+`
"created $($user.CreatedDate), confirmed $($user.isconfirmed)"
}
# API only permits max 100 at a time
if($toDelete.count -gt 99){
$result = Invoke-RestMethod -Header $headerParams `
-ContentType 'application/json' -Method 'POST' `
-Body (@{'UserIDs'=$toDelete} | ConvertTo-Json) -Uri $deleteURL
$toDelete = @()
}
}
if($toDelete.count -gt 0){
$result = Invoke-RestMethod -Header $headerParams `
-ContentType 'application/json' -Method 'POST' `
-Body (@{'UserIDs'=$toDelete}|ConvertTo-Json) -Uri $deleteURL
}
if($deleteCount -lt 1){
Write-Output "No client users matching query, nothing deleted"
} else {
Write-Output "Deleted $deleteCount users"
}