Logonme.ps1
enum DataType { Tenants OidcAuthorizations OidcTokens Saml2Tokens AuditEvents Users Links Devices Claims Roles Applications HotpTokens TotpTokens Fido2Tokens Passwords Templates Sessions } enum ConfigType { CertificatesSigning CertificatesEncryption CertificatesConnection CertificateStoreCurrentUser CertificateStoreLocalMachine CertificateStoreFile CertificateStoreSql CredsDirectoryService CredsOtp CredsPassword CredsSharedSecret CredsFido2 DirectoryAd DirectoryAdam DirectorySql DirectoryPortWise DirectoryNull BankIdV5 Sts StsClaimsMapIngress StsClaimsMapEgress StsRelyingParty Oidc OidcClient OidcClientSettings OidcResource OidcScope Saml2 Saml2IdentityProvider Saml2ServiceProvider AccountSelfService AuthenticationPolicy AuthenticationPolicyPath AuthenticationUserService AuthenticationProvisioningService AuthenticationEmailChallenge FormsMethodBankID FormsMethodCapcha FormsMethodEmailChallenge FormsMethodFido2 FormsMethodFido2Enrollment FormsMethodImpersonation FormsMethodOtpEnrollment FormsMethodPassword FormsMethodPasswordReset FormsMethodUserRegistration FormsMethodSaml2 FormsMethodSmsOtp FormsMethodSplash EmailSmtp EmailSendGrid SmsTelia SmsMobilstart SmsEmail SmsTurnpike UserVerificationBankID UserSyncLogonme4 UserSyncNull } class ApiEndpointConfigs { [Hashtable] $dataMap_ = @{ [DataType]::Tenants = '/data/tenants' [DataType]::OidcAuthorizations = '/data/oidc_authorizations' [DataType]::OidcTokens = '/data/oidc_tokens' [DataType]::Saml2Tokens = '/data/saml2_tokens' [DataType]::AuditEvents = '/data/audit_events' [DataType]::Users = '/data/users' [DataType]::Devices = '/data/user_devices' [DataType]::Claims = '/data/user_claims' [DataType]::Roles = '/data/user_roles' [DataType]::Applications = '/data/user_applications' [DataType]::Links = '/data/user_links' [DataType]::HotpTokens = '/data/creds_tokens_hotp' [DataType]::TotpTokens = '/data/creds_tokens_totp' [DataType]::Fido2Tokens = '/data/creds_tokens_fido2' [DataType]::Passwords = '/data/creds_password' [DataType]::Templates = '/data/templates' [DataType]::Sessions = '/data/sessions' } [Hashtable] $configMap_ = @{ [ConfigType]::CertificatesSigning = '/config/certificates_signing' [ConfigType]::CertificatesEncryption = '/config/certificates_encryption' [ConfigType]::CertificatesConnection = '/config/certificates_connection' [ConfigType]::CertificateStoreCurrentUser = '/config/certificates_store_current_user' [ConfigType]::CertificateStoreLocalMachine = '/config/certificates_store_local_machine' [ConfigType]::CertificateStoreFile = '/config/certificates_store_file' [ConfigType]::CertificateStoreSql = '/config/certificates_store_sql' [ConfigType]::CredsDirectoryService = '/config/credstore_directory' [ConfigType]::CredsOtp = '/config/credstore_otp' [ConfigType]::CredsPassword = '/config/credstore_password' [ConfigType]::CredsSharedSecret = '/config/credstore_shared_secret' [ConfigType]::CredsFido2 = '/config/credstore_fido2' [ConfigType]::DirectoryAd = '/config/directory_service_ad' [ConfigType]::DirectoryAdam = '/config/directory_service_adam' [ConfigType]::DirectoryNull = '/config/directory_service_null' [ConfigType]::DirectoryPortWise = '/config/directory_service_portwise' [ConfigType]::DirectorySql = '/config/directory_service_sql' [ConfigType]::BankIdV5 = '/config/eid_client_bankidv5' [ConfigType]::Sts = '/config/sts' [ConfigType]::StsClaimsMapIngress = '/config/sts_claimsmap_ingress' [ConfigType]::StsClaimsMapEgress = '/config/sts_claimsmap_egress' [ConfigType]::StsRelyingParty = '/config/sts_relying_party' [Configtype]::Oidc = '/config/oidc' [ConfigType]::OidcClient = '/config/oidc_client' [ConfigType]::OidcClientSettings = '/config/oidc_client_settings' [ConfigType]::OidcResource = '/config/oidc_resource' [ConfigType]::OidcScope = '/config/oidc_scope' [ConfigType]::Saml2 = '/config/saml2' [ConfigType]::Saml2ServiceProvider = '/config/saml2_service_provider' [ConfigType]::Saml2IdentityProvider = '/config/saml2_identity_provider' [ConfigType]::AccountSelfService = '/config/provisioning_account_self_service' [ConfigType]::AuthenticationPolicy = '/config/authentication_policy' [ConfigType]::AuthenticationPolicyPath = '/config/authentication_policy_path' [ConfigType]::AuthenticationUserService = '/config/authentication_user_service' [ConfigType]::AuthenticationProvisioningService = '/config/authentication_provisioning_service' [ConfigType]::AuthenticationEmailChallenge = '/config/authentication_email_challenge' [ConfigType]::FormsMethodBankID = '/config/forms_bankid' [ConfigType]::FormsMethodCapcha = '/config/forms_capcha' [ConfigType]::FormsMethodEmailChallenge = '/config/forms_email_challenge' [ConfigType]::FormsMethodFido2 = '/config/forms_fido2' [ConfigType]::FormsMethodFido2Enrollment = '/config/forms_fido2_enrollment' [ConfigType]::FormsMethodImpersonation = '/config/forms_impersonation' [ConfigType]::FormsMethodOtpEnrollment = '/config/forms_otp_enrollment' [ConfigType]::FormsMethodPassword = '/config/forms_password' [ConfigType]::FormsMethodPasswordReset = '/config/forms_password_reset' [ConfigType]::FormsMethodUserRegistration = '/config/forms_user_registration' [ConfigType]::FormsMethodSaml2 = '/config/forms_saml2' [ConfigType]::FormsMethodSmsOtp = '/config/forms_smsotp' [ConfigType]::FormsMethodSplash = '/config/forms_splash' [ConfigType]::EmailSmtp = '/config/notifier_mail_smtp' [ConfigType]::EmailSendGrid = '/config/notifier_mail_sendgrid' [ConfigType]::SmsTelia = '/config/notifier_sms_telia' [ConfigType]::SmsMobilstart = '/config/notifier_sms_mobilstart' [ConfigType]::SmsEmail = '/config/notifier_sms_email' [ConfigType]::SmsTurnpike = '/config/notifier_sms_turnpike' [ConfigType]::UserVerificationBankID = '/config/user_verification_bankid' [ConfigType]::UserSyncLogonme4 = '/config/usersync_logonme4' [ConfigType]::UserSyncNull = '/config/usersync_null' } [string] GetDataOdataPath([DataType] $dataType) { return $this.dataMap_[$dataType] } [string] GetConfigOdataPath([ConfigType] $configType) { return $this.configMap_[$configType] } } class ApiCredentials { [string] $AccessToken [string] $TokenType [int] $ExpiresIn; ApiCredentials([string]$accessToken, [string]$tokenType, [int]$expiresIn) { $this.AccessToken = $accessToken; $this.TokenType = $tokenType; $this.ExpiresIn = $expiresIn; } } class ApiConfig { [string] $Environment [string] $LoginServiceUrl [string] $ApiBaseUrl [string] $ApiTenantId [string] $ApiClientId [string] $ApiClientSecret [string] $ApiTimeout [string] $ApiSetupUsername [string] $ApiSetupPassword [string] $ServerRoot ApiConfig([string]$filePath, [string]$environment) { $ini = $this.GetIniContent($filePath) $this.Environment = $environment $this.LoginServiceUrl = $ini[$environment]["LoginServiceUrl"] $this.ApiBaseUrl = $ini[$environment]["ApiBaseUrl"] $this.ApiTenantId = $ini[$environment]["ApiTenantId"] $this.ApiClientId = $ini[$environment]["ApiClientId"] $this.ApiClientSecret = $ini[$environment]["ApiClientSecret"] $this.ApiTimeout = $ini[$environment]["ApiTimeout"] $this.ApiSetupUsername = $ini[$environment]["ApiSetupUsername"] $this.ApiSetupPassword = $ini[$environment]["ApiSetupPassword"] $this.ServerRoot = $ini[$environment]["ServerRoot"] } [HashTable] GetIniContent($filePath) { $ini = @{} $section = "" $CommentCount = 0 switch -regex -file $filePath { "^\[(.+)\]" { # Section $section = $matches[1] $ini[$section] = @{} $CommentCount = 0 } "^(;.*)$" { # Comment $value = $matches[1] $CommentCount = $CommentCount + 1 $name = "Comment" + $CommentCount $ini[$section][$name] = $value } "(.+?)\s*=(.*)" { # Key $name, $value = $matches[1..2] $ini[$section][$name] = $value } } return $ini } Dump() { Write-Host -Separator "-" Write-Host "Environment =" $this.Environment Write-Host "LoginServiceUrl =" $this.LoginServiceUrl Write-Host "ApiBaseUrl =" $this.ApiBaseUrl Write-Host "ApiTenantId =" $this.ApiTenantId Write-Host "ApiClientId =" $this.ApiClientId Write-Host "ApiClientSecret =" $this.ApiClientSecret Write-Host "ApiTimeout =" $this.ApiTimeout Write-Host "ApiSetupUsername =" $this.ApiSetupUsername Write-Host "ApiSetupPassword =" $this.ApiSetupPassword Write-Host -Separator "-" } DumpEnvironmentVariables() { Write-Host -Separator "-" Write-Host " LogonmeModuleFile = '$env:LogonmeModuleFile'" Write-Host " LogonmeVersion = '$env:LogonmeVersion'" Write-Host " LogonmeSharedVolumeDirectory = '$env:LogonmeSharedVolumeDirectory'" Write-Host " LogonmeTenant = '$env:LogonmeTenant'" Write-Host -Separator "-" } } if (-not ([System.Management.Automation.PSTypeName]'ServerCertificateValidationCallback').Type) { $certCallback = @" using System; using System.Net; using System.Net.Security; using System.Security.Cryptography.X509Certificates; public class ServerCertificateValidationCallback { public static void Ignore() { if(ServicePointManager.ServerCertificateValidationCallback ==null) { ServicePointManager.ServerCertificateValidationCallback += delegate ( Object obj, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors ) { return true; }; } } } "@ Add-Type $certCallback } [ServerCertificateValidationCallback]::Ignore() [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12; class ApiClient { [ApiConfig] $Config [ApiEndpointConfigs] $Endpoints [ApiCredentials] $Credentials ApiClient([ApiConfig] $config) { $this.Config = $config; $this.Endpoints = [ApiEndpointConfigs]::new(); $this.Credentials = $this.AquireAccessToken(); } [object] GetByFilter([string] $odataPath, [string] $odataFilter) { $uri = ($this.Config.ApiBaseUrl + $odataPath + '/?$filter=' + $odataFilter) $accessToken = $this.Credentials.AccessToken $headers = @{Authorization = "Bearer $accessToken" } $result = Invoke-RestMethod -SkipCertificateCheck -Uri $uri -Method Get -Headers $headers | ForEach-Object { $_ } if ($result -isnot [array]) { $result = @( $result ) } $result | ForEach-Object { $refUri = ($this.Config.ApiBaseUrl + $odataPath + '/' + $_.id) $_ | Add-Member -MemberType NoteProperty -Name "URL" -Value $refUri } return $result } [object] GetWithBasicAuth([string] $path) { $uri = ($this.Config.ApiBaseUrl + $path) $accessToken = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}@{1}:{2}" -f $this.Config.ApiSetupUsername, $this.Config.ApiTenantId, $this.Config.ApiSetupPassword))) $headers = @{Authorization = "Basic $accessToken" } return Invoke-RestMethod -SkipCertificateCheck -Uri $uri -Method Get -Headers $headers -ContentType "application/json" } [object] Get([string] $odataPath) { return $this.Get($odataPath, $null) } [object] Get([string] $odataPath, [object] $id) { $uri = ($this.Config.ApiBaseUrl + $odataPath + '/' + $id) $accessToken = $this.Credentials.AccessToken $headers = @{Authorization = "Bearer $accessToken" } $result = Invoke-RestMethod -SkipCertificateCheck -Uri $uri -Method Get -Headers $headers -ContentType "application/json" if ($result -isnot [array]) { $result | Add-Member -MemberType NoteProperty -Name "URL" -Value $uri $result = @( $result ) return $result; } $result | ForEach-Object { $_ | Add-Member -MemberType NoteProperty -Name "URL" -Value ($uri + $_.id) } return $result } [object] Post([string] $odataPath, [object] $objData) { $uri = ($this.Config.ApiBaseUrl + $odataPath) $accessToken = $this.Credentials.AccessToken $headers = @{Authorization = "Bearer $accessToken" } $obj = $objData.PsObject.Copy() $obj.PSObject.Properties.Remove("URL") $json = $objData | ConvertTo-Json return Invoke-RestMethod -SkipCertificateCheck -Uri $uri -Method Post -Body $json -Headers $headers -ContentType "application/json" } [object] Upload([string] $odataPath, [object] $id, [string] $uploadFile) { $uri = ($this.Config.ApiBaseUrl + $odataPath + '/upload/' + $id) $accessToken = $this.Credentials.AccessToken $headers = @{Authorization = "Bearer $accessToken" } $fileContents = Get-Item $uploadFile return Invoke-RestMethod -SkipCertificateCheck -Uri $uri -Method Post -ContentType "multipart/form-data" -Headers $headers -Form @{ file = $fileContents } } [object] Put([object] $objData) { $uri = $objData.URL $accessToken = $this.Credentials.AccessToken $headers = @{Authorization = "Bearer $accessToken" } $obj = $objData.PsObject.Copy() $obj.PSObject.Properties.Remove("URL") $json = $obj | ConvertTo-Json return Invoke-RestMethod -SkipCertificateCheck -Uri $uri -Method Put -Body $json -Headers $headers -ContentType "application/json" } [string] Delete([object] $objData) { $uri = $objData.URL $accessToken = $this.Credentials.AccessToken $headers = @{Authorization = "Bearer $accessToken" } return Invoke-RestMethod -SkipCertificateCheck -Uri $uri -Method Delete -Headers $headers -ContentType "application/json" } [ApiCredentials] AquireAccessToken() { $Uri = $this.Config.LoginServiceUrl + "/ls/" + $this.Config.ApiTenantId + "/connect/token" try { $Body = @{ grant_type = "client_credentials" client_id = $this.Config.ApiClientId client_secret = $this.Config.ApiClientSecret scope = 'management' redirect_uri = 'https://localhost/' } $res = Invoke-RestMethod -SkipCertificateCheck -Uri $uri -Method Post -Body $body -ContentType "application/x-www-form-urlencoded" return [ApiCredentials]::new($res.access_token, $res.token_type, $res.expires_in) } catch { $exception = $Error[0] Write-Warning "Failed to aquire access token from '$Uri', exception is '$exception'"; return $null } } } function Get-LogonmeApiClient { param( [Parameter( Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [Alias("env")] [string] $ConfigEnvironment = 'DEFAULT' ) $configFile = '.\Logonme.ini' $configTemplateFile = (Join-Path -Path $PSScriptRoot -ChildPath 'LogonmeTemplate.ini') if (-not (Test-Path -Path $configFile)) { Write-Warning "Logon.me API Client Configuration file '$configFile' does not exists, copying default template file '$configTemplateFile' to current directory" Copy-Item $configTemplateFile $configFile } $config = [ApiConfig]::new($configFile, $ConfigEnvironment) Write-Host "Imported configuration" -ForegroundColor green $config.Dump() switch ($config.ServerRoot) { '.' { $dataDirectory = (Get-Location).Path } Default { $dataDirectory = $config.ServerRoot } } $env:LogonmeTenant = ($config.ApiTenantId) $env:LogonmeSharedVolumeDirectory = ($dataDirectory) Write-Host "Exported environment variables" -ForegroundColor green $config.DumpEnvironmentVariables() return [ApiClient]::new($config) } function Get-LogonmeDockerComposeFile { $dockerComposeTemplateFile = (Join-Path -Path $PSScriptRoot -ChildPath 'docker-compose-template.yml') Get-Content -Path $dockerComposeTemplateFile } function Get-EnumValues { Param([string]$enum) $enumValues = @{} [enum]::getvalues([type]$enum) | ForEach-Object { $enumValues.add($_, $_.value__) } return $enumValues } function Get-LogonmeConfig { param( [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [Alias("client")] [ApiClient] $ApiClient , [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [Alias("type")] [ConfigType]$ConfigType , [Parameter( Mandatory = $false, ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $true) ] [Alias("filter")] [String]$OdataFilter ) $odataPath = $ApiClient.Endpoints.GetConfigOdataPath($ConfigType) if ($OdataFilter) { $ApiClient.GetByFilter($odataPath, $odataFilter) } else { $ApiClient.Get($odataPath) } } function Add-LogonmeConfigFromFileData { param( [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [Alias("client")] [ApiClient] $ApiClient , [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [Alias("type")] [ConfigType]$ConfigType , [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [string]$Id , [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [string]$UploadFile ) $odataPath = $ApiClient.Endpoints.GetConfigOdataPath($ConfigType) $ApiClient.Upload($odataPath, $id, $uploadFile) } function Add-LogonmeConfig { param( [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [Alias("client")] [ApiClient] $ApiClient , [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [Alias("type")] [ConfigType]$ConfigType , [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [string]$Id ) $odataPath = $ApiClient.Endpoints.GetConfigOdataPath($ConfigType) $obj = @{ id = $id } $temp = $ApiClient.Post($odataPath, $obj) $ApiClient.Get($odataPath, $id) } function Add-LogonmeData { param( [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [Alias("client")] [ApiClient] $ApiClient , [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [Alias("type")] [DataType]$DataType , [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [object]$obj ) $odataPath = $ApiClient.Endpoints.GetDataOdataPath($DataType) return $ApiClient.Post($odataPath, $obj) } function Get-LogonmeData { param( [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [Alias("client")] [ApiClient] $ApiClient , [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [Alias("type")] [DataType]$DataType , [Parameter( Mandatory = $false, ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $true) ] [Alias("filter")] [String]$OdataFilter ) $odataPath = $ApiClient.Endpoints.GetDataOdataPath($DataType) if ($OdataFilter) { $ApiClient.GetByFilter($odataPath, $odataFilter) } else { $ApiClient.Get($odataPath) } } function Remove-LogonmeObject { param ( [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [Alias("client")] [ApiClient] $ApiClient , [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [Alias("obj")] [object]$Object ) $ApiClient.Delete($Object) } function Set-LogonmeObject { param ( [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [Alias("client")] [ApiClient] $ApiClient , [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [Alias("obj")] [object]$Object ) $ApiClient.Put($Object) } Set-Alias -Name Set-LogonmeConfig -Value Set-LogonmeObject Set-Alias -Name Set-LogonmeData -Value Set-LogonmeObject Set-Alias -Name Remove-LogonmeConfig -Value Remove-LogonmeObject Set-Alias -Name Remove-LogonmeData -Value Remove-LogonmeObject enum SetupOperation { SeedConfiguration SeedData VerifyConfiguration VerifyLocalization DumpLocalization ClearConfigurationCache ClearSessionCache Drop } function Invoke-LogonmeSetup { param( [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [Alias("client")] [ApiClient] $ApiClient , [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [SetupOperation]$Operation , [Parameter( Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [Alias("env")] [string] $Environment = "develop" ) switch ( $Operation ) { SeedConfiguration { $ApiClient.GetWithBasicAuth("/setup/seed_configuration" + '?environment=' + $Environment) } SeedData { $ApiClient.GetWithBasicAuth("/setup/seed_data" + '?environment=' + $Environment) } VerifyConfiguration { $ApiClient.GetWithBasicAuth("/setup/verify_configuration") } VerifyLocalization { $uri = ($ApiClient.Config.LoginServiceUrl + '/ls/' + $ApiClient.Config.ApiTenantId + '/localization/verify') Invoke-RestMethod -SkipCertificateCheck -Method Get -Uri $uri } DumpLocalization { $uri = ($ApiClient.Config.LoginServiceUrl + '/ls/' + $ApiClient.Config.ApiTenantId + '/localization/i18n') Invoke-RestMethod -SkipCertificateCheck -Method Get -Uri $uri } ClearConfigurationCache { $uri = ($ApiClient.Config.LoginServiceUrl + '/ls/' + $ApiClient.Config.ApiTenantId + '/config/clear') $res = Invoke-RestMethod -SkipCertificateCheck -Method Get -Uri $uri Write-Host $res } ClearSessionCache { Get-LogonmeData -ApiClient $ApiClient -DataType Sessions | ForEach-Object { Logonme5-DeleteData -client $ApiClient -Object $_ } } Drop { $ApiClient.GetWithBasicAuth("/setup/drop") } } } function Get-LogonmeVersion { param( [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [Alias("client")] [ApiClient] $ApiClient ) $managementServiceVersion = $ApiClient.GetWithBasicAuth("/about/version") $uri = ($ApiClient.Config.LoginServiceUrl + '/ls/' + $ApiClient.Config.ApiTenantId + '/about/version') $loginServiceVersion = Invoke-RestMethod -SkipCertificateCheck -Method Get -Uri $uri Write-Host "Management-Service: $managementServiceVersion" Write-Host "Login-Service: $loginServiceVersion" } function MakeARestCall { param( [string] $Uri , [string] $AccessToken , [string] $Username , [string] $LogFile ) try { $Headers = @{Authorization = "Bearer $AccessToken" } return Invoke-RestMethod -SkipCertificateCheck -Uri $Uri -Method Get -Headers $Headers -ContentType "application/json" -Verbose } catch { Write-Warning "$Username FAILED" Add-Content $LogFile $Username } } function Sync-LogonmeUsers { param( [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [Alias("client")] [ApiClient] $ApiClient , [Parameter( Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [Alias("if")] [string]$ImportFile , [Parameter( Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [Alias("uid")] [string]$Username ) if (-not ($ImportFile -or $Username)) { Write-Host "parameter ``ImportFile`` or ``Username`` must be specified" return } $baseUrl = $ApiClient.Config.ApiBaseUrl $accessToken = $ApiClient.Credentials.AccessToken $funcDef = $function:MakeARestCall.ToString() $logFile = "sync-user-errors.txt" if (Test-Path $logFile -PathType leaf) { Clear-Content $logFile } if ($ImportFile) { $users = Get-Content $importFile } if ($Username) { $users = @( $Username ) } $users | ForEach-Object -Parallel { $function:MakeARestCall = $using:funcDef $uri = $using:baseUrl + '/user_provisioning/sync-user?loginName=' + $_ MakeARestCall -Uri $uri -AccessToken $using:accessToken -Username $_ -LogFile $using:logFile } -ThrottleLimit 10 } enum AdfsConfigOperation { Install Uninstall } function Get-LogonmeAdfsConfig { param( [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [Alias("client")] [ApiClient] $ApiClient , [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [AdfsConfigOperation]$Operation ) switch ( $Operation ) { Install { $ApiClient.Get('/config/adfs/install') } Uninstall { $ApiClient.Get('/config/adfs/uninstall') } } } function Find-LogonmeUsers { param( [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [Alias("client")] [ApiClient] $ApiClient , [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [Alias("l")] [string]$Login ) $escLogin = [uri]::EscapeDataString($Login) $result = New-Object System.Collections.ArrayList $u = Get-LogonmeData -ApiClient $ApiClient -DataType Users -OdataFilter "username eq '$escLogin'" if ($null -ne $u) { $result.Add($u) | Out-Null } $users = Get-LogonmeData -ApiClient $ApiClient -DataType Users -OdataFilter "emailAddress eq '$escLogin'" if ($null -ne $users -and $users.count -gt 0) { $result += $users } $users = Get-LogonmeData -ApiClient $ApiClient -DataType Users -OdataFilter "mobilePhone eq '$escLogin'" if ($null -ne $users -and $users.count -gt 0) { $result += $users } return $result } function Get-LogonmeUserData { param( [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [Alias("client")] [ApiClient] $ApiClient , [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [Alias("l")] [string]$Login , [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [DataType]$DataType ) $users = Find-LogonmeUsers -ApiClient $ApiClient -Login $Login if ($null -ne $users) { if ($users.count -gt 1) { Write-Error "User search retured more than multiple users, use 'username' resolve this" return } $u = $users[0] $uid = $u.id return Get-LogonmeData -ApiClient $ApiClient -DataType $DataType -OdataFilter "userId eq '$uid'" } } function Add-LogonmeUserRole { param( [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [Alias("client")] [ApiClient] $ApiClient , [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [Alias("l")] [string]$Login , [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [string]$Name , [Parameter( Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [string]$Issuer , [Parameter( Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [string]$ClaimType ) if (-not $Issuer) { $Issuer = "Logonme5" # default Issuer } if (-not $ClaimType) { $ClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" # default claim type } $users = Find-LogonmeUsers -ApiClient $ApiClient -Login $login if ($null -ne $users) { if ($users.count -gt 1) { Write-Error "User search retured more than multiple users, use 'username' resolve this" return } $u = $users[0] $obj = @{ id = "rid-" + [guid]::NewGuid().ToString("n") userId = $u.id issuer = $Issuer name = $Name claimType = $ClaimType } $temp = Add-LogonmeData -ApiClient $ApiClient -DataType Roles -obj $obj if ($temp) { $uid = $obj.userId $rid = $obj.id Write-Host "Successfully created role '$Name' ($rid) for user '$uid'" return Get-LogonmeData -ApiClient $ApiClient -DataType Roles -OdataFilter "id eq '$rid'" } Write-Error "Failed to create role '$Name' for user '$u'" } else { Write-Error "User not found" } } function Export-LogonmeData { param( [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [Alias("client")] [ApiClient] $ApiClient ) Get-LogonmeData -ApiClient $ApiClient -DataType Tenants Get-LogonmeData -ApiClient $ApiClient -DataType OidcAuthorizations Get-LogonmeData -ApiClient $ApiClient -DataType OidcTokens Get-LogonmeData -ApiClient $ApiClient -DataType Saml2Tokens Get-LogonmeData -ApiClient $ApiClient -DataType AuditEvents Get-LogonmeData -ApiClient $ApiClient -DataType Users Get-LogonmeData -ApiClient $ApiClient -DataType Devices Get-LogonmeData -ApiClient $ApiClient -DataType Claims Get-LogonmeData -ApiClient $ApiClient -DataType Roles Get-LogonmeData -ApiClient $ApiClient -DataType Applications Get-LogonmeData -ApiClient $ApiClient -DataType Links Get-LogonmeData -ApiClient $ApiClient -DataType HotpTokens Get-LogonmeData -ApiClient $ApiClient -DataType TotpTokens Get-LogonmeData -ApiClient $ApiClient -DataType Fido2Tokens Get-LogonmeData -ApiClient $ApiClient -DataType Passwords Get-LogonmeData -ApiClient $ApiClient -DataType Sessions } function Export-LogonmeConfigs { param( [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true) ] [Alias("client")] [ApiClient] $ApiClient ) Get-LogonmeConfig -ApiClient $ApiClient -ConfigType CertificatesSigning Get-LogonmeConfig -ApiClient $ApiClient -ConfigType CertificatesEncryption Get-LogonmeConfig -ApiClient $ApiClient -ConfigType CertificatesConnection Get-LogonmeConfig -ApiClient $ApiClient -ConfigType CertificateStoreCurrentUser Get-LogonmeConfig -ApiClient $ApiClient -ConfigType CertificateStoreLocalMachine Get-LogonmeConfig -ApiClient $ApiClient -ConfigType CertificateStoreFile Get-LogonmeConfig -ApiClient $ApiClient -ConfigType CertificateStoreSql Get-LogonmeConfig -ApiClient $ApiClient -ConfigType CredsDirectoryService Get-LogonmeConfig -ApiClient $ApiClient -ConfigType CredsOtp Get-LogonmeConfig -ApiClient $ApiClient -ConfigType CredsPassword Get-LogonmeConfig -ApiClient $ApiClient -ConfigType CredsSharedSecret Get-LogonmeConfig -ApiClient $ApiClient -ConfigType DirectoryAd Get-LogonmeConfig -ApiClient $ApiClient -ConfigType DirectoryAdam Get-LogonmeConfig -ApiClient $ApiClient -ConfigType DirectorySql Get-LogonmeConfig -ApiClient $ApiClient -ConfigType DirectoryPortWise Get-LogonmeConfig -ApiClient $ApiClient -ConfigType BankIdV5 Get-LogonmeConfig -ApiClient $ApiClient -ConfigType Sts Get-LogonmeConfig -ApiClient $ApiClient -ConfigType StsClaimsMapIngress Get-LogonmeConfig -ApiClient $ApiClient -ConfigType StsClaimsMapEgress Get-LogonmeConfig -ApiClient $ApiClient -ConfigType StsRelyingParty Get-LogonmeConfig -ApiClient $ApiClient -ConfigType Oidc Get-LogonmeConfig -ApiClient $ApiClient -ConfigType OidcClient Get-LogonmeConfig -ApiClient $ApiClient -ConfigType OidcClientSettings Get-LogonmeConfig -ApiClient $ApiClient -ConfigType OidcResource Get-LogonmeConfig -ApiClient $ApiClient -ConfigType OidcScope Get-LogonmeConfig -ApiClient $ApiClient -ConfigType Saml2 Get-LogonmeConfig -ApiClient $ApiClient -ConfigType Saml2ServiceProvider Get-LogonmeConfig -ApiClient $ApiClient -ConfigType Saml2IdentityProvider Get-LogonmeConfig -ApiClient $ApiClient -ConfigType AccountSelfService Get-LogonmeConfig -ApiClient $ApiClient -ConfigType AuthenticationPolicy Get-LogonmeConfig -ApiClient $ApiClient -ConfigType AuthenticationPolicyPath Get-LogonmeConfig -ApiClient $ApiClient -ConfigType AuthenticationUserService Get-LogonmeConfig -ApiClient $ApiClient -ConfigType AuthenticationProvisioningService Get-LogonmeConfig -ApiClient $ApiClient -ConfigType AuthenticationEmailChallenge Get-LogonmeConfig -ApiClient $ApiClient -ConfigType FormsMethodBankID Get-LogonmeConfig -ApiClient $ApiClient -ConfigType FormsMethodCapcha Get-LogonmeConfig -ApiClient $ApiClient -ConfigType FormsMethodEmailChallenge Get-LogonmeConfig -ApiClient $ApiClient -ConfigType FormsMethodFido2 Get-LogonmeConfig -ApiClient $ApiClient -ConfigType FormsMethodFido2Enrollment Get-LogonmeConfig -ApiClient $ApiClient -ConfigType FormsMethodImpersonation Get-LogonmeConfig -ApiClient $ApiClient -ConfigType FormsMethodOtpEnrollment Get-LogonmeConfig -ApiClient $ApiClient -ConfigType FormsMethodPassword Get-LogonmeConfig -ApiClient $ApiClient -ConfigType FormsMethodPasswordReset Get-LogonmeConfig -ApiClient $ApiClient -ConfigType FormsMethodUserRegistration Get-LogonmeConfig -ApiClient $ApiClient -ConfigType FormsMethodSmsOtp Get-LogonmeConfig -ApiClient $ApiClient -ConfigType FormsMethodSplash Get-LogonmeConfig -ApiClient $ApiClient -ConfigType EmailSmtp Get-LogonmeConfig -ApiClient $ApiClient -ConfigType EmailSendGrid Get-LogonmeConfig -ApiClient $ApiClient -ConfigType SmsTelia Get-LogonmeConfig -ApiClient $ApiClient -ConfigType SmsMobilstart Get-LogonmeConfig -ApiClient $ApiClient -ConfigType SmsEmail Get-LogonmeConfig -ApiClient $ApiClient -ConfigType SmsTurnpike Get-LogonmeConfig -ApiClient $ApiClient -ConfigType UserVerificationBankID Get-LogonmeConfig -ApiClient $ApiClient -ConfigType UserSyncLogonme4 Get-LogonmeConfig -ApiClient $ApiClient -ConfigType UserSyncNull } |