Templates/Plugins/Invoke-PluginGSheetStaff.ps1
|
#Spreadsheet Data Staff — IDBridge plugin template # TemplateVersion: 1 <# Shipped with the IDBridge module and copied to <RootPath>\Plugins by Install-IDBridge. Every placeholder value below must be edited for your district before enabling the plugin in IDBridgeConfig.psd1 — the plugin throws until the spreadsheet ID is set. Pairs with the published source-sheet template (see docs/getting-started.md); share the spreadsheet with the service-account email (Get-IDBridgeGoogleServiceAccountEmail). #> <# Secrets are stored in the IDBridge secret vault (encrypted files under <RootPath>\Vault). Add/change them with: Set Passphrase API Key if in Use Set-IDBridgeSecret -Name 'ApiKey-Passphrase' Set Passphrase Nonce for staff if in Use Set-IDBridgeSecret -Name 'ApiKey-PassphraseNonceStaff' #> function Invoke-PluginGSheetStaff { [CmdletBinding()] param () $PersonTypeGeneric = "Staff" $GoogleSheetConfig = @{ SheetID = "YOUR-SPREADSHEET-ID" # From the sheet URL: docs.google.com/spreadsheets/d/<this part>/edit SheetRange = 'Staff' SafetyCheckCount = 100 # Your expected staff row count — the run aborts if the sheet returns fewer than SafetyCheckPercentage% of this SafetyCheckPercentage = 75 } if ($GoogleSheetConfig.SheetID -eq "YOUR-SPREADSHEET-ID") { Throw "Invoke-PluginGSheetStaff: this plugin template still has placeholder values. Edit $($PSCommandPath) for your district before enabling it." } #Generic Config $DomainName = "yourdistrict.org" $Company = "Your School District" #AD Config $ADProvision = $true $ADUserRootOU = "OU=YourDistrict,DC=yourdomain,DC=local" $ADPassPrefix = 'Temp-' $ADChangePasswordAtLogon = $true $ADPasswordType = 'WORD' #Must be API-PASSPHRASE, WORD, RANDOM, FSPIN #Google Config $GoogleProvision = $true $GoogleUserRootOU = "/YourDistrict" $GooglePassPrefix = 'Temp-' $GoogleChangePasswordAtLogon = $false $GooglePasswordType = 'RANDOM' #Must be API-PASSPHRASE, WORD, RANDOM, FSPIN # Staff PersonTypes that should get PersonTypeID = "3" — adjust to your sheet's PersonType values $PersonTypeThree = @( 'Administrator', 'Teacher', 'Principal', 'Secretary', 'Support Staff' ) #Passphrase API Configuration - only fetch the secrets from the vault when a password type uses them $usePassphraseAPI = ($ADPasswordType -eq 'API-PASSPHRASE') -or ($GooglePasswordType -eq 'API-PASSPHRASE') $passphraseNonce = $null $passphraseAuthToken = $null if ($usePassphraseAPI) { try { $passphraseNonce = Get-IDBridgeSecret -Name 'ApiKey-PassphraseNonceStaff' $passphraseAuthToken = Get-IDBridgeSecret -Name 'ApiKey-Passphrase' } catch { Throw "Error retrieving passphrase API secrets from the vault: $($_)" } } $PassphraseAPI = @{ Nonce = $passphraseNonce #Shared secret nonce Mode = "WORDS" #Must be WORDS or VERBNOUN WordCount = 3 #How many words the passphrase will have. Only applies to WORDS mode AuthToken = $passphraseAuthToken #API Auth token in SecureString Format } try { $params = @{ sheetID = $GoogleSheetConfig.SheetID sheetRange = $GoogleSheetConfig.SheetRange userCount = $GoogleSheetConfig.SafetyCheckCount userCountSafetyPercentage = $GoogleSheetConfig.SafetyCheckPercentage } $data = Get-SourceDataGSheet @params } catch { Throw "Error retrieving data from Google Sheet: $($_)" } $dataNormalized = foreach ($item in $data) { # --- IsActive Property --- if ($item.TerminationDate -and ([datetime]$item.TerminationDate -lt (Get-Date))) { $isActive = $false } else { $isActive = $true } # Groups # Determine automatic groups based on PersonType # The optional Get-CustomStaffGroups helper (bottom of this file) encodes your district's # group policy — dynamic group assignment based on the person's role and location. $groupsAutomatic = $null $groupsAutomatic = if (Test-Path Function:\Get-CustomStaffGroups) { Get-CustomStaffGroups -building $item.Building -personType $item.PersonType } #Proposed Groups $proposedGroupList = @() if ($groupsAutomatic) {$proposedGroupList += $groupsAutomatic} if (-not [string]::IsNullOrEmpty($item.ApplicationGroups)) {$proposedGroupList += ($item.ApplicationGroups -split ",").trim()} if (-not [string]::IsNullOrEmpty($item.EmailGroups)) {$proposedGroupList += ($item.EmailGroups -split ",").trim()} #Key Setup AD $keyAD = $null if ($ADPasswordType -eq "Word") { if ($item.Word) { $keyAD = "$($ADPassPrefix)$($item.Word)" } } else { $keyAD = "$((New-Guid).Guid)" } #Key Setup Google $keyGoogle = $null if ($GooglePasswordType -eq "Word") { if ($item.Word) { $keyGoogle = "$($GooglePassPrefix)$($item.Word)" } } else { $keyGoogle = "$((New-Guid).Guid)" } # --- Build the standardized source record via the module factory --- $recordFields = @{ PersonID = $item.PersonID NameFirst = $item.NameFirst NameLast = $item.NameLast Username = $item.Username Building = $item.Building JobTitle = $item.JobTitle Company = $Company UPN = "$($item.Username)@$($DomainName)" PersonTypeID = if ($item.PersonType -in $PersonTypeThree) { "3" } else { "2" } IDBActive = $isActive GroupsProposed = ($proposedGroupList | Select-Object -Unique) PersonType = $item.PersonType ProvisionAD = $ADProvision ADOrganizationalUnit = "OU=$($item.PersonType),OU=$($PersonTypeGeneric),$($ADUserRootOU)" ADOrganizationalUnitTrash = "OU=$(Get-Date -Format yyyy),OU=$($PersonTypeGeneric),OU=Trash,$($ADUserRootOU)" ADChangePasswordAtLogon = $ADChangePasswordAtLogon ADPassphraseAPI = if ($ADPasswordType -eq "API-PASSPHRASE") { $PassphraseAPI } else { $null } ADKey = if ($keyAD) { ConvertTo-SecureString -String $keyAD -AsPlainText -Force } else { $null } ProvisionGoogle = $GoogleProvision GoogleOrganizationalUnit = "$($GoogleUserRootOU)/$($PersonTypeGeneric)/$($item.PersonType)" GoogleOrganizationalUnitTrash = "/Trash/$($PersonTypeGeneric)/$(Get-Date -Format yyyy)" GoogleChangePasswordAtLogon = $GoogleChangePasswordAtLogon GooglePassphraseAPI = if ($GooglePasswordType -eq "API-PASSPHRASE") { $PassphraseAPI } else { $null } GoogleKey = if ($keyGoogle) { ConvertTo-SecureString -String $keyGoogle -AsPlainText -Force } else { $null } } New-IDBridgeSourceRecord @recordFields } return $dataNormalized } <# Sample Data Returned by Get-SourceDataGSheet: PersonID : 100001 NameFirst : Jane NameLast : Doe Username : doej Building : Sample Elementary PersonType : Principal JobTitle : Principal TerminationDate : ApplicationGroups : APP_HelpDesk_Submitter, APP_Door_Access EmailGroups : Word : trainer Process : TRUE ForceDisable : FALSE GoogleOUOverride : FALSE PersonID : 999999 NameFirst : Test NameLast : Test Username : test123 Building : District Wide PersonType : Administrator JobTitle : TEST TITLE TerminationDate : 12/21/2025 ApplicationGroups : EmailGroups : All Staff Word : poem Process : TRUE ForceDisable : FALSE GoogleOUOverride : FALSE #> function Get-CustomStaffGroups() { [cmdletbinding()] Param( [parameter(Mandatory=$true)] $building, [parameter(Mandatory=$true)] $personType ) # OPTIONAL helper — encode your district's group policy here (or delete the function; the # plugin only calls it when it exists). A minimal starting point is below; build it out # with building/person-type allow- and deny-lists as your policy grows. #Initialize Group Variable $groups = @() #All Staff ######------------###### $groups += ("All Staff") ######------------###### #Building Staff (ex. "Sample Elementary Staff") ######------------###### if ($building) { $groups += ($building + " Staff") } ######------------###### #All Professional Staff ######------------###### #personTypes to include $groupAllProfessionalPersonType = @( "Administrator" "Principal" "Teacher" ) if ($personType -in $groupAllProfessionalPersonType) { $groups += ("All Professional Staff") } ######------------###### return $groups } |