EasitManagementFramework.psm1
function Backup-EasitFolder { [CmdletBinding()] param ( [Parameter(Mandatory)] [string] $FolderToBackup, [Parameter(Mandatory)] [string] $DestinationFolder, [Parameter()] [string] $ArchiveName, [Parameter()] [boolean] $Cleanup ) begin { Write-Verbose "$($MyInvocation.MyCommand) initialized" } process { $today = Get-Date -Format "yyyyMMdd" $now = Get-Date -Format "yyyyMMdd_HHmmss" $todayDestinationFolder = Join-Path -Path "$DestinationFolder" -ChildPath "$today" if ([string]::IsNullOrWhiteSpace($ArchiveName)) { $leaf = Split-Path $FolderToBackup -Leaf $ArchiveName = "${leaf}_${now}" } Write-Verbose "Using $ArchiveName as ArchiveName" if (!(Test-Path -Path $todayDestinationFolder)) { try { $todayDestinationFolder = (New-Item -Path $DestinationFolder -Name "$today" -ItemType Directory).FullName Write-Verbose "Created $todayDestinationFolder" } catch { throw $_ } } $tempDirectory = [System.IO.Path]::GetTempPath() [string] $tempDirectoryName = [System.Guid]::NewGuid() $tempWorkingDirectoryPath = Join-Path -Path $tempDirectory -ChildPath $tempDirectoryName $tempWorkingDirectory = New-Item -ItemType Directory -Path $tempWorkingDirectoryPath try { Write-Verbose "Copying folder to temp location" Copy-Item -Path $FolderToBackup -Destination $tempWorkingDirectory $tempFolderToBackup = Join-Path -Path $tempWorkingDirectory -ChildPath "$leaf" } catch { throw $_ } Write-Verbose "Using $todayDestinationFolder as todayDestinationFolder" $zipFile = Join-Path -Path $todayDestinationFolder -ChildPath "$ArchiveName.zip" try { Add-Type -Assembly System.IO.Compression.FileSystem $compressionLevel = [IO.Compression.CompressionLevel]::Optimal if (Test-Path -Path $FolderToBackup -PathType Leaf) { Write-Verbose "PathType is Leaf" try { $zip = [System.IO.Compression.ZipFile]::Open($zipFile, 'create') $zip.Dispose() $zip = [System.IO.Compression.ZipFile]::Open($zipFile, 'update') [System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($zip, $tempFolderToBackup, $leaf, $compressionLevel) | Out-Null $zip.Dispose() } catch { $zip.Dispose() Remove-Item $zipFile -Recurse -Force -Confirm:$false -InformationAction SilentlyContinue -ErrorAction SilentlyContinue Remove-Item $zip -Recurse -Force -Confirm:$false -InformationAction SilentlyContinue -ErrorAction SilentlyContinue Remove-Item $tempWorkingDirectoryPath -Recurse -Force -Confirm:$false -InformationAction SilentlyContinue -ErrorAction SilentlyContinue throw $_ } } if (Test-Path -Path $FolderToBackup -PathType Container) { Write-Verbose "PathType is Container" try { [IO.Compression.ZipFile]::CreateFromDirectory($tempFolderToBackup, $zipFile, $compressionLevel, $false) } catch { Remove-Item $zipFile -Recurse -Force -Confirm:$false -InformationAction SilentlyContinue -ErrorAction SilentlyContinue Remove-Item $tempWorkingDirectoryPath -Recurse -Force -Confirm:$false -InformationAction SilentlyContinue -ErrorAction SilentlyContinue throw $_ } } Remove-Item $tempWorkingDirectoryPath -Recurse -Force -Confirm:$false -InformationAction SilentlyContinue -ErrorAction SilentlyContinue Write-Verbose "Created zip archive for $FolderToBackup" } catch { throw $_ } if ($Cleanup) { try { Remove-Item $FolderToBackup -Recurse -Force -Confirm:$false -InformationAction SilentlyContinue Write-Verbose "Removed $FolderToBackup" } catch { throw $_ } } else { Write-Verbose "Cleanup has not been specified, leaving $FolderToBackup as is" } } end { Write-Verbose "$($MyInvocation.MyCommand) completed" } } function Convert-EasitLogEntryToPsObject { [CmdletBinding(HelpURI="https://github.com/easitab/EasitManagementFramework/blob/main/docs/v1/Convert-EasitLogEntryToPsObject.md")] param ( [Parameter(ValueFromPipeline)] [string] $String, [Parameter()] [string] $Source ) begin { Write-Verbose "$($MyInvocation.MyCommand) initialized" } process { Write-Verbose "Selecting strings from entry" $stringDate = Select-String -InputObject $String -Pattern '\d{4}-\d{2}-\d{2}' $stringDate = "$($stringDate.Matches.Value)" Write-Debug "stringDate = $stringDate" $stringTime = Select-String -InputObject $String -Pattern '\d{2}:\d{2}:\d{2}\.\d{3}' $stringTime = "$($stringTime.Matches.Value)" Write-Debug "stringTime = $stringTime" $stringLevel = Select-String -InputObject $String -Pattern 'FATAL|ERROR|WARN|INFO|DEBUG|TRACE' $stringLevel = "$($stringLevel.Matches.Value)" Write-Debug "stringLevel = $stringLevel" $stringMessage = Select-String -InputObject $String -Pattern '- .+\[' $stringMessage = "$($stringMessage.Matches.Value)" $stringMessage = $stringMessage.TrimStart('- ') $stringMessage = $stringMessage.TrimEnd('[') Write-Debug "stringMessage = $stringMessage" $stringClass = Select-String -InputObject $String -Pattern '\[[\w\.]+\]$' $stringClass = "$($stringClass.Matches.Value)" $stringClass = $stringClass.TrimStart('[') $stringClass = $stringClass.TrimEnd(']') Write-Debug "stringClass = $stringClass" if (Select-String -InputObject $String -Pattern '\]\s?(\r|\n)+' -Quiet) { $stringStack = Select-String -InputObject $String -Pattern '\- [\w|\W|\n\r]*' $stringStack = "$($stringStack.Matches.Value)" $stringStack = $stringStack.TrimStart("- $stringMessage [$stringClass]") $stringStack = $stringStack.TrimStart() Write-Debug "stringStack = $stringStack" } else { $stringStack = $null } Write-Verbose "Creating object from entry strings" $returnObject = [PSCustomObject]@{ Date = "$stringDate" Time = "$stringTime" Level = "$stringLevel" Class = "$stringClass" Message = "$stringMessage" FullStackMessage = "$stringStack" Source = "$Source" } Write-Verbose "Returning entry as object" return $returnObject } end { Write-Verbose "$($MyInvocation.MyCommand) completed" } } function Convert-EmailRequestConfigfile { [CmdletBinding()] param ( [Parameter(Mandatory)] [string]$Path ) begin { Write-Verbose "$($MyInvocation.MyCommand) initialized" } process { try { $xmlObject = New-Object XML } catch { throw $_ } if (Test-Path $Path) { try { $xmlObject.Load($Path) } catch { throw $_ } } else { throw "Unable to find $Path" } foreach ($entry in $xmlObject.configuration.entries.GetEnumerator()) { try { $erMailConfigAsPSObject = New-Object PSObject } catch { throw $_ } foreach ($mainProperty in $entry.properties.GetEnumerator()) { Write-Verbose "Adding property $($mainProperty.name) = $($mainProperty.value)" Add-Member -InputObject $erMailConfigAsPSObject -MemberType NoteProperty -Name "$($mainProperty.name)" -Value "$($mainProperty.value)" } foreach ($sourceProperty in $entry.source.properties.GetEnumerator()) { Write-Verbose "Adding property $($sourceProperty.name) = $($sourceProperty.value)" Add-Member -InputObject $erMailConfigAsPSObject -MemberType NoteProperty -Name "$($sourceProperty.name)" -Value "$($sourceProperty.value)" } foreach ($destinationProperty in $entry.destination.properties.GetEnumerator()) { Write-Verbose "Adding property $($destinationProperty.name) = $($destinationProperty.value)" Add-Member -InputObject $erMailConfigAsPSObject -MemberType NoteProperty -Name "$($destinationProperty.name)" -Value "$($destinationProperty.value)" } Write-Verbose "Adding property sourceType = $($entry.source.type)" Add-Member -InputObject $erMailConfigAsPSObject -MemberType NoteProperty -Name 'sourceType' -Value "$($entry.source.type)" Add-Member -InputObject $erMailConfigAsPSObject -MemberType NoteProperty -Name 'Path' -Value "$Path" $erMailConfigAsPSObject } } end { Write-Verbose "$($MyInvocation.MyCommand) completed" } } function Convert-KeytoolResult { [CmdletBinding()] param ( [Parameter()] [String[]] $InputString, [Parameter()] [String] $ListCerts ) begin { Write-Verbose "$($MyInvocation.MyCommand) initialized" } process { if ($InputString) { if (Select-String -Pattern 'java.lang.Exception:' -InputObject $InputString) { Write-Verbose "Input is an exception" $InputString } elseif (Select-String -Pattern '-rfc.*-alias.*-keystore.*-cacerts.*-storepass.*' -InputObject $InputString) { Write-Verbose "Input is help section" $InputString } elseif ($ListCerts -match 'true') { Write-Verbose "ListCerts = $ListCerts" $returnObject = New-Object -TypeName psobject $entryId = 1 foreach ($string in $InputString) { if ($string.Length -gt 1) { $Matches = $null Write-Verbose "String = $string" if ($string -match 'Keystore|Nyckellager') { Write-Verbose "String matches Keystore|Nyckellager" $string -match '^(.+): (.+)' | Out-Null $propName = $Matches[1] $propName = $propName.TrimStart() $propValue = $Matches[2] $propValue = $propValue.TrimEnd() $propValue = $propValue.TrimStart() Write-Verbose "$propName = $propValue" $returnObject | Add-Member -MemberType Noteproperty -Name "$propName" -Value "$propValue" } elseif ($string -cmatch '(\d+) poster|post|entry|entries') { Write-Verbose "String matches poster|post|entry|entries" $string -match '(\d+) poster|post|entry|entries' | Out-Null $propName = 'NumberOfEntriesInStore' $propValue = $Matches[1] Write-Verbose "$propName = $propValue" $returnObject | Add-Member -MemberType Noteproperty -Name "$propName" -Value "$propValue" } elseif ($string -match '.*, .*, .*,') { Write-Verbose "Split details" $string -match '((.*), (.*), (.*)),' | Out-Null $tempPropValues = $Matches[1] $tempPropValuesArray = $tempPropValues -split ',' $returnObject | Add-Member -MemberType Noteproperty -Name "CertificateAlias_$entryId" -Value "$($tempPropValuesArray[0])" foreach ($tempPropValue in $tempPropValuesArray) { Write-Verbose "$tempPropValue" } } elseif ($string -match '.*(\(.*\)): (.*)') { $string -match '.*(\(.*\)): (.*)' | Out-Null $propName = "CertificateFingerprint $($Matches[1])_$entryId" $propValue = $Matches[2] $returnObject | Add-Member -MemberType Noteproperty -Name "$propName" -Value "$propValue" $entryId++ } } } $returnObject } else { Write-Verbose "Input is valid" $returnObject = New-Object -TypeName psobject foreach ($string in $InputString) { if ($string.Length -gt 1 -and $string -match '^\s*(.+):{1} (.+)') { if ($string -match '^\d{2}(\d|[A-Z])\d' -or $string -match '^\s+\[' -or $string -match '^\#\d+' -or $string -match 'access' -or $string -match 'PathLen') { Write-Verbose "Not a relevant string, $string" } else { Write-Verbose "String = $string" $string -match '^\s*(.+):{1} (.+)' | Out-Null $propName = $Matches[1] $propName = $propName.TrimStart() $propValue = $Matches[2] $propValue = $propValue.TrimEnd() $propValue = $propValue.TrimStart() Write-Verbose "$propName = $propValue" if ($propName -match '.*alias.*') { Write-Verbose "alias" $propName = 'CertificateAlias' $propValue = $propValue } elseif ($propName -match 'Skapat|Creation') { Write-Verbose "skapat" $propName = 'CreationDate' $propValue = $propValue } elseif ($propName -match 'post|entry') { Write-Verbose "post" $propName = 'EntryType' $propValue = $propValue } elseif ($propName -match '.gare|owner') { Write-Verbose "owner" $propName = 'Owner' $propValue = $propValue } elseif ($propName -match 'utf.{1}rdare|issuer') { Write-Verbose "issuer" $propName = 'Issuer' $propValue = $propValue } elseif ($propName -match 'Serienummer|Serial') { Write-Verbose "Serienummer" $propName = 'SerialNumber' $propValue = $propValue } elseif ($propName -match 'Giltigt|Valid') { Write-Verbose "Giltigt" $propName = 'ValidFrom' $propName2 = 'ValidUntil' $string -match '(?>Giltigt |Valid ).*: (.*),? (?>till|until): (.*)' | Out-Null $propValue = $Matches[1] $propValue = $propValue.TrimEnd(',') $propValue2 = $Matches[2] if (!(${returnObject}.${propName2})) { $returnObject | Add-Member -MemberType Noteproperty -Name "$propName2" -Value "$propValue2" } } elseif ($propName -match '\w{2,3}\d{1,3}') { Write-Verbose "hashes" $propName = "CertificateFingerprint ($propName)" } elseif ($propName -match 'Signaturalgoritmnamn|Signature') { Write-Verbose "SignatureAlgorithmName" $propName = 'SignatureAlgorithmName' } elseif ($propName -match '(?>Algoritm f|Signature)') { Write-Verbose "Signature" $propName = 'AlgorithmForOpenKey' } else { Write-Verbose "$propName matches nothing" } if (!(${returnObject}.${propName})) { $returnObject | Add-Member -MemberType Noteproperty -Name "$propName" -Value "$propValue" } } } else { Write-Verbose "String ($string) is not relevant" } $Matches = $null } $returnObject } } } end { Write-Verbose "$($MyInvocation.MyCommand) completed" } } function Convert-XmlToPSObject { [CmdletBinding()] param ( [Parameter(Mandatory)] [xml] $XmlObject, [Parameter()] [switch] $SystemProperties ) begin { Write-Verbose "$($MyInvocation.MyCommand) initialized" } process { $returnObject = New-Object -TypeName PSObject if ($SystemProperties) { foreach ($entry in $XmlObject.properties.entry) { Write-Verbose "Adding $($entry.key) = $($entry.'#text')" try { Add-Member -InputObject $returnObject -MemberType Noteproperty -Name "$($entry.key)" -Value "$($entry.'#text')" } catch { throw $_ } } } return $returnObject } end { Write-Verbose "$($MyInvocation.MyCommand) completed" } } function Get-DatabaseDetails { [CmdletBinding()] param ( [Parameter(Mandatory)] [string]$Uri ) begin { Write-Verbose "$($MyInvocation.MyCommand) initialized" } process { $returnObject = New-Object PSObject $multiConnDets = $false if ($Uri -match 'sqlserver') { Write-Verbose "ConnString is for MSSQL" $supportedProtocol = $true $dbConnectionDetails = $Uri -split ';' if ($dbConnectionDetails.Count -ne '1') { $multiConnDets = $true } } if ($Uri -match 'mysql') { Write-Verbose "ConnString is for MySQL" $supportedProtocol = $false $cleanDbUrl = $Uri -replace '.+\:.+\:\/\/','' Write-Verbose "cleanDbUrl = $cleanDbUrl" $dbName = Split-Path $cleanDbUrl -Leaf $dbServerUrl = Split-Path $cleanDbUrl -Parent $dbServerUrlDetails = $dbServerUrl -split ':' $dbServerName = $dbServerUrlDetails[0] if ($dbServerUrlDetails[1]) { $dbServerPort = $dbServerUrlDetails[1] } else { $dbServerPort = 3306 } } if ($multiConnDets) { Write-Verbose "Multiple connections details" foreach ($dbConnectionDetail in $dbConnectionDetails) { Write-Verbose $dbConnectionDetail if ($dbConnectionDetail -match '.+\:.+\:\/\/.*') { $dbServerDetails = $dbConnectionDetail -replace '.+\:.+\:\/\/','' if ($dbServerDetails -match '\\\\') { Write-Verbose "$dbServerDetails contains \\" $dbInstanceDetails = $dbServerDetails -split '\\\\' Write-Verbose "dbInstanceDetails = $dbInstanceDetails" $dbInstance = $dbInstanceDetails[1] $dbServerDetails = $dbInstanceDetails[0] } if ($dbServerDetails -match ':') { Write-Verbose "$dbServerDetails contains :" $dbServerUrlDetails = $dbServerDetails -split ':' Write-Verbose "dbServerUrlDetails = $dbServerUrlDetails" $dbServerName = $dbServerUrlDetails[0] $dbServerPort = $dbServerUrlDetails[1] } if (!($dbServerName)) { $dbServerName = $dbServerDetails } if (!($dbServerPort)) { $dbServerPort = 1433 } if (!($dbInstance)) { $dbInstance = $null } } if ($dbConnectionDetail -match 'databaseName.*') { $dbName = $dbConnectionDetail -replace 'databaseName=','' } } } try { Write-Verbose "dbServerName = $dbServerName" $returnObject | Add-Member -MemberType NoteProperty -Name 'dbServerName' -Value "$dbServerName" Write-Verbose "dbServerPort = $dbServerPort" $returnObject | Add-Member -MemberType NoteProperty -Name 'dbServerPort' -Value "$dbServerPort" Write-Verbose "dbName = $dbName" $returnObject | Add-Member -MemberType NoteProperty -Name 'dbName' -Value "$dbName" Write-Verbose "dbInstance = $dbInstance" $returnObject | Add-Member -MemberType NoteProperty -Name 'dbInstance' -Value "$dbInstance" Write-Verbose "supportedProtocol = $supportedProtocol" $returnObject | Add-Member -MemberType NoteProperty -Name 'supportedProtocol' -Value "$supportedProtocol" return $returnObject } catch { throw $_ } } end { Write-Verbose "$($MyInvocation.MyCommand) completed" } } function Get-EasitJavaKeytool { [CmdletBinding()] param ( [Parameter()] [string] $Path ) begin { Write-Verbose "$($MyInvocation.MyCommand) initialized" } process { $javaPath = Join-Path -Path $Path -ChildPath 'Java' if (Test-Path $javaPath) { try { Get-ChildItem "$javaPath\*" -Include 'keytool.exe' -Recurse | Sort-Object {[version]$_.VersionInfo.FileVersion} | Select-Object -Last 1 } catch { throw $_ } } else { throw "$javaPath is not a valid path.." } } end { Write-Verbose "$($MyInvocation.MyCommand) completed" } } function Get-EasitService { [CmdletBinding()] param ( [Parameter(Mandatory)] [string] $ServiceName ) begin { Write-Verbose "$($MyInvocation.MyCommand) initialized" } process { try { $service = Get-CimInstance -ClassName Win32_Service -Filter "Name Like '$ServiceName'" Write-Verbose "Found service $($service.Name)" } catch { throw "Unable to find a service with a name like $ServiceName" } return $service } end { Write-Verbose "$($MyInvocation.MyCommand) completed" } } function Get-EasitWarFile { [CmdletBinding()] param ( [Parameter(Mandatory)] [string]$Path, [Parameter(Mandatory)] [string]$Name ) begin { Write-Verbose "$($MyInvocation.MyCommand) initialized" } process { if (!(Test-Path -Path $Path)) { throw "Unable to find $Path" } try { $folders = Get-ChildItem -Path $Path -Exclude 'files', 'solr*' -Directory } catch { throw $_ } foreach ($folder in $folders) { try { Get-ChildItem -Path $folder -Include "$Name" -File -Recurse } catch { throw $_ } } } end { Write-Verbose "$($MyInvocation.MyCommand) completed" } } function Import-EMFXMLData { [CmdletBinding()] param ( [Parameter(Mandatory)] [string] $Path, [Parameter()] [switch] $ReturnAsPSObject, [Parameter()] [switch] $Validate ) begin { Write-Verbose "$($MyInvocation.MyCommand) initialized" } process { Write-Verbose "Process block start" if ($Validate) { try { Test-EMFXMLData -Path $Path Write-Verbose 'XML validated successfully' } catch { throw $_ } } else { Write-Verbose "Skipping validation" } $xmlObject = New-Object System.Xml.XmlDocument try { $xmlObject.Load($Path) Write-Verbose 'Loaded XML-file to XML-object' } catch { throw $_ } if ($ReturnAsPSObject) { try { $psObject = Convert-XmlToPSObject -XmlObject $xmlObject -SystemProperties } catch { throw $_ } return $psObject } else { return $xmlObject } Write-Verbose "Process block end" } end { Write-Verbose "$($MyInvocation.MyCommand) completed" } } function Set-EasitService { [CmdletBinding()] param ( [Parameter(Mandatory)] [CimInstance] $Service, [Parameter(Mandatory)] [ValidateSet('StartService','StopService')] [string] $Action ) begin { Write-Verbose "$($MyInvocation.MyCommand) initialized" $waitingTime = 0 } process { if ($Action -eq 'StartService') { $waitForServiceState = 'Running' } if ($Action -eq 'StopService') { $waitForServiceState = 'Stopped' } Write-Information "Invoking method $Action on $($Service.Name)" try { Invoke-CimMethod -InputObject $Service -MethodName "$Action" | Out-Null } catch { throw $_ } try { do { Write-Verbose "Waiting for service to complete method invokation" Start-Sleep -Seconds 5 $waitingTime += 5 $serviceToCheck = Get-CimInstance -InputObject $Service } while ($serviceToCheck.State -ne "$waitForServiceState" -AND $waitingTime -le 240) if ($waitingTime -gt 240) { Write-Warning "Time to invoke method $Action exceeded 2 minutes" } } catch { throw $_ } return $serviceToCheck } end { Write-Verbose "$($MyInvocation.MyCommand) completed" } } function Test-ConfigurationSetting { [CmdletBinding()] param ( [Parameter()] [hashtable]$Hashtable, [Parameter()] [System.Xml.XmlDocument]$XmlObject ) begin { Write-Verbose "$($MyInvocation.MyCommand) initialized" $validatePathSetting = 'SystemRoot','EmailRequestRoot','EasitRoot','BackupRoot','TomcatRoot','ImportClientRoot','UpdateResourceDirectory' } process { $allSettingsPassedTest = $true if ($Hashtable) { foreach ($configSetting in $configurationSettings.GetEnumerator()) { $configSettingName = "$($configSetting.Key)" $configSettingValue = "$($configSetting.Value)" Write-Verbose "Validating configuration setting $configSettingName" if ($configSettingName -in $validatePathSetting) { if (Test-Path "$configSettingValue" -IsValid) { $validationResult = Test-Path "$configSettingValue" } else { $validationResult = $false } } if ($configSettingName -eq 'ServiceName') { $validationResult = Get-Service -Name "$configSettingValue" -ErrorAction SilentlyContinue } if ($configSettingName -eq 'WarName') { $systemRoot = $configurationSettings['SystemRoot'] $validationResult = Get-ChildItem -Path "$systemRoot" -Recurse -Include "${configSettingValue}.war" -ErrorAction SilentlyContinue } if ($configSettingName -eq 'StoredBackupProcedure') { # Unable to validate this setting $validationResult = $true } if (!($validationResult)) { Write-Warning "Configuration setting $configSettingName ($configSettingValue) failed validation" $allSettingsPassedTest = $false } } if ($allSettingsPassedTest) { Write-Information "Validation OK" -InformationAction Continue } } if ($XmlObject) { foreach ($system in $XmlObject.systems.ChildNodes) { Write-Information "Validating settings for configuration $($system.Name)" -InformationAction Continue foreach ($configSetting in $system.ChildNodes) { $configSettingName = "$($configSetting.Name)" $configSettingValue = "$($configSetting.InnerText)" Write-Verbose "Validating configuration setting $configSettingName" if ($configSettingName -in $validatePathSetting) { if (Test-Path "$configSettingValue" -IsValid) { $validationResult = Test-Path "$configSettingValue" } else { $validationResult = $false } } if ($configSettingName -eq 'ServiceName') { $validationResult = Get-Service -Name "$configSettingValue" -ErrorAction SilentlyContinue } if ($configSettingName -eq 'WarName') { $systemRoot = $system.GetElementsByTagName('SystemRoot') $systemRoot = $systemRoot.'#text' $validationResult = Get-EasitWarFile -Path "$systemRoot" -Name "${configSettingValue}.war" } if (!($validationResult)) { Write-Warning "Configuration setting $configSettingName ($configSettingValue) failed validation" $allSettingsPassedTest = $false } } if ($allSettingsPassedTest) { Write-Information "Validation OK" -InformationAction Continue } } } return } end { Write-Verbose "$($MyInvocation.MyCommand) completed" } } function Test-ForFileLock { [CmdletBinding(HelpURI="https://github.com/easitab/EasitManagementFramework/blob/main/docs/v1/Test-ForFileLock.md")] param ( [Parameter(Mandatory)] [string]$FilePath ) begin { Write-Verbose "$($MyInvocation.MyCommand) initialized" } process { Write-Verbose "Checking if $FilePath is locked" $fileInfo = New-Object System.IO.FileInfo $FilePath try { $fileStream = $fileInfo.Open( [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read) Write-Verbose "$FilePath is not locked" $returnValue = $false } catch { Write-Verbose "$FilePath is locked" $returnValue = $true } $fileStream.Close() $fileStream.Dispose() return $returnValue } end { Write-Verbose "$($MyInvocation.MyCommand) completed" } } function Add-CertificateToEasitTrustStore { [CmdletBinding(HelpURI="https://github.com/easitab/EasitManagementFramework/blob/main/docs/v1/Add-CertificateToEasitTrustStore.md")] [Alias("ACTET", "AddCert")] param ( [Parameter(ParameterSetName='LiteralPath',Mandatory=$true)] [string] $LiteralPath, [Parameter(ParameterSetName='Path')] [string] $Path, [Parameter(ParameterSetName='Path',Mandatory=$true)] [string] $TrustStoreName, [Parameter(Mandatory=$true)] [string] $Certificate, [Parameter()] [string] $Keytool, [Parameter(Mandatory=$true)] [Alias('keystorepass','truststorepass')] [string] $StorePass, [Parameter(Mandatory=$true)] [string] $CertificateAlias, [Parameter()] [switch] $TrustCaCerts, [Parameter()] [switch] $NoPrompt, [Parameter()] [string] $EmfHome = "${env:ALLUSERSPROFILE}\EMF", [Parameter()] [string] $EmfConfigurationFileName = 'emfConfig.xml', [Parameter()] [Alias('system')] [string] $EmfConfigurationName = 'Prod' ) begin { Write-Verbose "$($MyInvocation.MyCommand) initialized" $emfConfig = Get-EMFConfig -EMFHome $EmfHome -ConfigurationFileName $EmfConfigurationFileName -ConfigurationName $EmfConfigurationName } process { if (!($Keytool)) { try { $Keytool = Get-EasitJavaKeytool -Path $emfConfig.EasitRoot Write-Verbose "Keytool = $Keytool" } catch { throw $_ } } if ($Path -and $TrustStoreName) { $trustStorePath = Join-Path -Path $Path -ChildPath $TrustStoreName if (Test-Path $trustStorePath) { Write-Verbose "Using truststore at $trustStorePath" } else { throw "Unable to find $TrustStoreName in $Path" } } if ($Path -and !($TrustStoreName)) { throw "You need to provide a TrustStoreName when specifying Path. Otherwise use LiteralPath." } if ($LiteralPath) { if (Test-Path $LiteralPath) { $trustStorePath = $LiteralPath Write-Verbose "Using truststore at $trustStorePath" } else { throw "Unable to find $LiteralPath" } } if (Test-Path -Path $Certificate) { Write-Verbose "Will try to import file: $Certificate" } else { throw "Unable to find certificate $Certificate" } if ($NoPrompt) { if ($TrustCaCerts) { Write-Verbose "Executing: $Keytool -importcert -trustcacerts -noprompt -alias $CertificateAlias -file $Certificate -keystore $trustStorePath -storepass $StorePass" $result = & "$Keytool" -importcert -trustcacerts -noprompt -alias "$CertificateAlias" -file "$Certificate" -keystore "$trustStorePath" -storepass "$StorePass" } else { Write-Verbose "Executing: $Keytool -importcert -noprompt -alias $CertificateAlias -file $Certificate -keystore $trustStorePath -storepass $StorePass" $result = & "$Keytool" -importcert -noprompt -alias "$CertificateAlias" -file "$Certificate" -keystore "$trustStorePath" -storepass "$StorePass" } } else { if ($TrustCaCerts) { Write-Verbose "Executing: $Keytool -importcert -trustcacerts -alias $CertificateAlias -file $Certificate -keystore $trustStorePath -storepass $StorePass" $result = & "$Keytool" -importcert -trustcacerts -noprompt -alias "$CertificateAlias" -file "$Certificate" -keystore "$trustStorePath" -storepass "$StorePass" } else { Write-Verbose "Executing: $Keytool -importcert -alias $CertificateAlias -file $Certificate -keystore $trustStorePath -storepass $StorePass" $result = & "$Keytool" -importcert -noprompt -alias "$CertificateAlias" -file "$Certificate" -keystore "$trustStorePath" -storepass "$StorePass" } } if (!($result)) { break } else { return $result } } end { Write-Verbose "$($MyInvocation.MyCommand) completed" } } Export-ModuleMember -Function Add-CertificateToEasitTrustStore function Disable-EasitScheduledTask { [CmdletBinding()] param ( [Parameter(ValueFromPipeline, ParameterSetName = 'InputObject')] [Microsoft.Management.Infrastructure.CimInstance[]] $InputObject, [Parameter(ParameterSetName = 'TaskName')] [string[]] $TaskName, [Parameter()] [switch] $AsJob ) begin { Write-Verbose "$($MyInvocation.MyCommand) initialized" } process { if ($InputObject) { $paramArgs = @{ TaskName = "$($InputObject.TaskName)" } Write-Verbose "TaskName set to $($InputObject.TaskName)" } if ($TaskName) { $paramArgs = @{ TaskName = "$TaskName" } Write-Verbose "TaskName set to $TaskName" } if ($AsJob) { $paramArgs = @{ AsJob = $true } Write-Verbose "Parameter AsJob specified" } try { Disable-ScheduledTask @paramArgs Write-Verbose "Task with name $TaskName disabled" } catch { throw $_ } } end { Write-Verbose "$($MyInvocation.MyCommand) completed" } } Export-ModuleMember -Function Disable-EasitScheduledTask function Enable-EasitScheduledTask { [CmdletBinding()] param ( [Parameter(ValueFromPipeline, ParameterSetName = 'InputObject')] [Microsoft.Management.Infrastructure.CimInstance[]] $InputObject, [Parameter(ParameterSetName = 'TaskName')] [string[]] $TaskName, [Parameter()] [switch] $AsJob ) begin { Write-Verbose "$($MyInvocation.MyCommand) initialized.." } process { if ($InputObject) { $paramArgs = @{ TaskName = "$($InputObject.TaskName)" } Write-Verbose "TaskName set to $($InputObject.TaskName)" } if ($TaskName) { $paramArgs = @{ TaskName = "$TaskName" } Write-Verbose "TaskName set to $TaskName" } if ($AsJob) { $paramArgs = @{ AsJob = $true } Write-Verbose "Parameter AsJob specified" } try { Enable-ScheduledTask @paramArgs Write-Verbose "Task with name $TaskName enabled" } catch { throw $_ } } end { Write-Verbose "$($MyInvocation.MyCommand) completed" } } Export-ModuleMember -Function Enable-EasitScheduledTask function Get-EasitEmailRequestMailbox { [CmdletBinding()] param ( [Parameter()] [string] $EmfHome = "${env:ALLUSERSPROFILE}\EMF", [Parameter()] [string] $EmfConfigurationFileName = 'emfConfig.xml', [Parameter()] [string] $EmfConfigurationName = 'Prod', [Parameter()] [string[]] $EmailRequestConfigurationFilename = '*config*.xml', [Parameter()] [Alias('Mailbox')] [string[]] $MailboxName ) begin { Write-Verbose "$($MyInvocation.MyCommand) initialized" try { $emfConfig = Get-EMFConfig -Home $EmfHome -ConfigurationFileName $EmfConfigurationFileName -ConfigurationName $EmfConfigurationName Write-Verbose "Found EMF Config" } catch { throw $_ } } process { $erXmlConfigFiles = @() foreach ($xmlConfigFilenames in $EmailRequestConfigurationFilename) { try { $erXmlConfigFiles += Get-ChildItem -Path "$($emfConfig.EmailRequestRoot)" -Include "$xmlConfigFilenames" -Recurse -Force } catch { throw $_ } } foreach ($erXmlConfigFile in $erXmlConfigFiles) { if ($MailboxName) { foreach ($Mailbox in $MailboxName) { if ($Mailbox -match '\*') { try { Convert-EmailRequestConfigfile $erXmlConfigFile | Where-Object {$_.displayName -Like "$Mailbox"} } catch { throw $_ } } else { try { Convert-EmailRequestConfigfile $erXmlConfigFile | Where-Object {$_.displayName -eq "$Mailbox"} } catch { throw $_ } } } } else { try { Convert-EmailRequestConfigfile $erXmlConfigFile } catch { throw $_ } } } } end { Write-Verbose "$($MyInvocation.MyCommand) completed" } } Export-ModuleMember -Function Get-EasitEmailRequestMailbox function Get-EasitLog { [CmdletBinding(DefaultParameterSetName='Configuration',HelpURI="https://github.com/easitab/EasitManagementFramework/blob/main/docs/v1/Get-EasitLog.md")] param ( [Parameter(ParameterSetName='LiteralPath')] [string]$LiteralPath, [Parameter(ParameterSetName='Path')] [string]$Path, [Parameter(Mandatory,ParameterSetName='Path')] [string]$LogFilename, [Parameter(ParameterSetName = 'Configuration')] [string] $EmfHome = "${env:ALLUSERSPROFILE}\EMF", [Parameter(ParameterSetName = 'Configuration')] [string] $EmfConfigurationFileName = 'emfConfig.xml', [Parameter(Mandatory,Position=0,ParameterSetName = 'Configuration')] [Alias('system')] [string] $EmfConfigurationName ) begin { Write-Verbose "$($MyInvocation.MyCommand) initialized" } process { if (!($LiteralPath) -and !($Path)) { Write-Verbose "LiteralPath and Path are not provided.." try { Write-Verbose "Looking for EMF-Config" $emfConfig = Get-EMFConfig -Home $EmfHome -ConfigurationFileName $EmfConfigurationFileName -ConfigurationName $EmfConfigurationName } catch { throw $_ } try { Write-Verbose "Joining path $($emfConfig.SystemRoot) and 'logs'" $Path = Join-Path "$($emfConfig.SystemRoot)" -ChildPath 'logs' -ErrorAction Stop } catch { throw $_ } if (Test-Path -Path $Path) { Write-Verbose "Path = $Path" } else { Write-Verbose "Path = $Path" throw "Unable to find $Path. A valid path to logfiles need to be provided. This can be done with the following parameters 'LiteralPath' or 'Path'. If you would like to use your EMF-configurationfile place it in ${env:ALLUSERSPROFILE}\EMF and specify a value for SystemRoot (ex. D:\Easit\Systems\Prod) or use 'EmfHome', 'EmfConfigurationFileName' and 'EmfConfigurationName' parameters to take advantage from it." } } elseif ($Path) { if (Test-Path -Path $Path) { Write-Verbose "Path = $Path" } else { throw "Unable to find $Path" } } elseif ($LiteralPath) { if (Test-Path -Path $LiteralPath) { $Path = $LiteralPath } else { throw "Unable to find $LiteralPath" } } else { throw "Unable to figure out what to do. Either provide a 'LiteralPath', 'Path' and 'LogFilename' or a valid EMF-configurationfile" } if (!($LiteralPath)) { # If-block need to be performed for Get-ChildItem to work. if (Test-Path $Path -PathType Container) { if (!($Path -match '\\$')) { $Path = "${Path}\" } } if ($LogFilename) { $gciParams = @{ Include = "*${LogFilename}*.log" Exclude = $null } } else { $LogFilename = 'easit' $gciParams = @{ Include = '*easit*.log' Exclude = '*stderr*', '*stdout*' } } try { $files = Get-ChildItem "${Path}*" @gciParams -ErrorAction Stop Write-Verbose "Collected all files matching *${LogFilename}*.log in $Path" } catch { throw $_ } } if ($LiteralPath) { try { $files = Get-ChildItem "$Path" -ErrorAction Stop Write-Verbose "Collected $Path" } catch { throw $_ } } foreach ($file in $files) { $logData += "`n1##$($file.Fullname)##`n" Write-Verbose "Getting content of $file" try { $encoding = [System.Text.Encoding]::UTF8 $fileStream = [System.IO.FileStream]::new($file, 'Open', 'Read', 'ReadWrite') $textReader = [System.IO.StreamReader]::new($fileStream,$encoding) $collectedData = $textReader.ReadToEnd() if ([string]::IsNullOrWhiteSpace($collectedData)) { Write-Verbose "$file did not contain any entries, skipping" continue } if (!([string]::IsNullOrWhiteSpace($collectedData))) { $collectedDataContainsData = $true } $logData += $collectedData Write-Verbose "Content collected" } catch [System.IO.IOException] { Write-Warning "$file locked by other process, skipping" continue } catch { Write-Warning "$($_.Exception), skipping" continue } } $returnObject = @() if ($collectedDataContainsData) { Write-Verbose "Splitting entries in logfile" $logEvents = $logData -split "(?=[\r|\n]+\d)" Write-Verbose "Converting entries to objects" foreach ($logEvent in $logEvents) { $logEvent = $logEvent.TrimEnd() $logEvent = $logEvent.TrimStart() if (Select-String -InputObject $logEvent -Pattern '##.+##' -Quiet) { $source = Select-String -InputObject $logEvent -Pattern '##.+##' $source = "$($source.Matches.Value)" $source = $source.TrimStart('##') $source = $source.TrimEnd('##') Write-Verbose "source = $source" } else { if ($logEvent.length -gt 0) { try { $returnObject += $logEvent | Convert-EasitLogEntryToPsObject -Source "$source" } catch { throw $_ } } } } Write-Verbose "Returning converted entries as objects" return $returnObject } else { Write-Verbose "Log collection did not produce any entries" return } } end { Write-Verbose "$($MyInvocation.MyCommand) completed" } } Export-ModuleMember -Function Get-EasitLog function Get-EasitScheduledTask { [CmdletBinding()] param ( [Parameter()] [switch] $EmailRequest, [Parameter()] [switch] $ImportClient ) begin { Write-Verbose "$($MyInvocation.MyCommand) initialized" } process { $easitTasks = @() if (!($EmailRequest) -and !($ImportClient)) { try { $easitTasks = Get-ScheduledTask -TaskName "*easit*" } catch { throw $_ } } if ($EmailRequest) { try { $easitErTask = Get-ScheduledTask -TaskName "*easit*" | Where-Object -Property 'TaskName' -Match -Value 'mail' $easitTasks += $easitErTask } catch { throw $_ } } if ($ImportClient) { try { $easitIcTask = Get-ScheduledTask -TaskName "*easit*" | Where-Object -Property 'TaskName' -Match -Value 'import' $easitTasks += $easitIcTask } catch { throw $_ } } foreach ($task in $easitTasks) { $taskDetails = Get-ScheduledTaskInfo -InputObject $task $taskDetails | Add-Member -NotePropertyName Status -NotePropertyValue $task.State $taskDetails | Format-Table TaskName, LastRunTime, NextRunTime, Status -AutoSize } } end { Write-Verbose "$($MyInvocation.MyCommand) completed" } } Export-ModuleMember -Function Get-EasitScheduledTask function Get-EasitTrustStoreCertificate { [CmdletBinding(HelpURI="https://github.com/easitab/EasitManagementFramework/blob/main/docs/v1/Get-EasitTrustStoreCertificate")] param ( [Parameter(ParameterSetName='LiteralPath',Mandatory=$true)] [string] $LiteralPath, [Parameter(ParameterSetName='Path')] [string] $Path, [Parameter(ParameterSetName='Path',Mandatory=$true)] [string] $TrustStoreName, [Parameter()] [string] $Keytool, [Parameter(Mandatory=$true)] [Alias('keystorepass','truststorepass')] [string] $StorePass, [Parameter()] [string] $CertificateAlias, [Parameter()] [string] $EmfHome = "${env:ALLUSERSPROFILE}\EMF", [Parameter()] [string] $EmfConfigurationFileName = 'emfConfig.xml', [Parameter()] [Alias('system')] [string] $EmfConfigurationName = 'Prod' ) begin { Write-Verbose "$($MyInvocation.MyCommand) initialized" $emfConfig = Get-EMFConfig -EMFHome $EmfHome -ConfigurationFileName $EmfConfigurationFileName -ConfigurationName $EmfConfigurationName } process { if (!($Keytool)) { try { $Keytool = Get-EasitJavaKeytool -Path $emfConfig.EasitRoot Write-Verbose "Keytool = $Keytool" } catch { throw $_ } } if ($Path -and $TrustStoreName) { $trustStorePath = Join-Path -Path $Path -ChildPath $TrustStoreName if (Test-Path $trustStorePath) { Write-Verbose "Using truststore at $trustStorePath" } else { throw "Unable to find $TrustStoreName in $Path" } } if ($Path -and !($TrustStoreName)) { throw "You need to provide a TrustStoreName when specifying Path. Otherwise use LiteralPath." } if ($LiteralPath) { if (Test-Path $LiteralPath) { $trustStorePath = $LiteralPath Write-Verbose "Using truststore at $trustStorePath" } else { throw "Unable to find $LiteralPath" } } if ($StorePass) { if ($CertificateAlias) { Write-Verbose "Executing: $Keytool -list -v -alias $CertificateAlias -keystore $trustStorePath -storepass $StorePass" $result = & "$Keytool" -list -v -alias "$CertificateAlias" -keystore "$trustStorePath" -storepass "$StorePass" $listCerts = 'false' } else { Write-Verbose "Executing: $Keytool -list -keystore $trustStorePath -storepass $StorePass" $result = & "$Keytool" -list -keystore "$trustStorePath" -storepass "$StorePass" $listCerts = 'true' } } else { if ($CertificateAlias) { Write-Verbose "Executing: $Keytool -list -v -alias $CertificateAlias -keystore $trustStorePath" $result = & "$Keytool" -list -v -alias "$CertificateAlias" -keystore "$trustStorePath" $listCerts = 'false' } else { Write-Verbose "Executing: $Keytool -list -keystore $trustStorePath" $result = & "$Keytool" -list -keystore "$trustStorePath" $listCerts = 'true' } } if (!($result)) { break } Write-Verbose "$result" Convert-KeytoolResult -InputString $result -ListCerts "$listCerts" } end { Write-Verbose "$($MyInvocation.MyCommand) completed" } } Export-ModuleMember -Function Get-EasitTrustStoreCertificate function Get-EMFConfig { [CmdletBinding()] param ( [Parameter()] [Alias('Home')] [string] $EMFHome = "${env:ALLUSERSPROFILE}\EMF", [Parameter()] [Alias('ConfigurationFileName','ConfigFile','ConfigFileName')] [string] $EmfConfigurationFileName = 'emfConfig.xml', [Parameter(Mandatory, Position=0)] [Alias('ConfigurationName','ConfigName')] [string] $EmfConfigurationName ) begin { Write-Verbose "$($MyInvocation.MyCommand) initialized" } process { if (Test-Path "$EMFHome\$EmfConfigurationFileName") { Write-Verbose "Found $EMFHome\$EmfConfigurationFileName" } else { throw [System.IO.FileNotFoundException] "$EMFHome\$EmfConfigurationFileName does not exist" } Write-Verbose "Retrieving configurations data" try { $configurationFileData = Import-EMFXMLData -Path "$EMFHome\$EmfConfigurationFileName" Write-Verbose "Configuration data retrieved" } catch { throw $_ } if ($configurationFileData.systems.$EmfConfigurationName) { Write-Verbose "Found configuration named $EmfConfigurationName" } else { throw "No configuration found named $EmfConfigurationName" } $returnObject = New-Object -TypeName psobject $configProperties = $configurationFileData.systems.$EmfConfigurationName foreach ($property in $configProperties.ChildNodes) { $returnObject | Add-Member -MemberType NoteProperty -Name "$($property.Name)" -Value "$($property.InnerText)" } return $returnObject } end { Write-Verbose "$($MyInvocation.MyCommand) completed" } } Export-ModuleMember -Function Get-EMFConfig function Initialize-EasitManagementFramework { [CmdletBinding()] param ( [Parameter()] [Alias('Home')] [string] $EMFHome = "${env:ALLUSERSPROFILE}\EMF", [Parameter()] [string] $ConfigURL = 'https://raw.githubusercontent.com/easitab/EasitManagementFramework/development/configurations/emfConfig.xml', [Parameter()] [string] $SchemaURL = 'https://raw.githubusercontent.com/easitab/EasitManagementFramework/development/schemas/emfConfig.xsd', [Parameter()] [string] $ConfigName = 'emfConfig.xml', [Parameter()] [string] $SchemaName = 'emfConfig.xsd' ) begin { Write-Verbose "$($MyInvocation.MyCommand) initialized!" $ProgressPreference = 'SilentlyContinue' } process { if (!(Test-Path -Path $EMFHome)) { try { $null = New-Item -Path "${env:ALLUSERSPROFILE}" -Name 'EMF' -ItemType Directory Write-Information "Created directory EMF in ${env:ALLUSERSPROFILE}" -InformationAction Continue } catch { throw $_ } } else { Write-Verbose "Found $EMFHome" } try { $wc = New-Object System.Net.WebClient Write-Verbose "Created WebClient" } catch { throw $_ } Write-Information "Downloading assets..." -InformationAction Continue try { $output1 = Join-Path -Path "$EMFHome" -ChildPath "$ConfigName" $wc.DownloadFile($ConfigURL, $output1) Write-Verbose "Download of $ConfigName complete" } catch { throw $_ } try { $output2 = Join-Path -Path "$EMFHome" -ChildPath "$SchemaName" $wc.DownloadFile($SchemaURL, $output2) Write-Verbose "Download of $SchemaName complete" } catch { throw $_ } Write-Information "Download of assets complete" -InformationAction Continue } end { $ProgressPreference = 'Continue' Write-Verbose "$($MyInvocation.MyCommand) completed" } } Export-ModuleMember -Function Initialize-EasitManagementFramework function Invoke-EasitGOHealthCheck { [CmdletBinding(HelpURI="https://github.com/easitab/EasitManagementFramework/blob/main/docs/v1/Invoke-EasitGOHealthCheck.md")] param ( [Parameter()] [string] $EmfHome = "${env:ALLUSERSPROFILE}\EMF", [Parameter()] [string] $EmfConfigurationFileName = 'emfConfig.xml', [Parameter(Mandatory)] [Alias('system')] [string] $EmfConfigurationName ) begin { Write-Verbose "$($MyInvocation.MyCommand) initialized" $emfConfig = Get-EMFConfig -EMFHome $EmfHome -ConfigurationFileName $EmfConfigurationFileName -ConfigurationName $EmfConfigurationName } process { $healthCheckResultObject = New-Object -TypeName PSObject if (Test-Path -Path "$($emfConfig.SystemRoot)") { Write-Verbose "Evalutating system drive.." try { $systemDriveLetter = Split-Path -Path "$($emfConfig.SystemRoot)" -Qualifier } catch { throw $_ } if ($systemDriveLetter) { Write-Verbose "Using systemDriveLetter $systemDriveLetter to evaluate drive state" $systemDriveDetails = Get-CimInstance Win32_LogicalDisk -Filter DriveType=3 | Where-Object -Property DeviceID -EQ "$systemDriveLetter" | Select-Object DeviceID, @{'Name'='Size'; 'Expression'={[math]::truncate($_.size / 1GB)}}, @{'Name'='Freespace'; 'Expression'={[math]::truncate($_.freespace / 1GB)}} try { $healthCheckResultObject | Add-Member -MemberType NoteProperty -Name EvaluatedDrive -Value "$systemDriveLetter" $healthCheckResultObject | Add-Member -MemberType NoteProperty -Name DriveSize -Value "$($systemDriveDetails.Size)" $healthCheckResultObject | Add-Member -MemberType NoteProperty -Name DriveFreespace -Value "$($systemDriveDetails.Freespace)" } catch { Write-Warning "$($_.Exception)" } } else { Write-Warning "Unable to find systemDriveLetter, skipping evaluation of system drive" } } else { Write-Warning "Unable to find path for systemroot from emfConfig ($($emfConfig.SystemRoot)), skipping evalution of system drive" } Write-Verbose "Evalution of system drive complete" Write-Verbose "Evalutating system memory.." try { $memoryInfo = Get-CimInstance win32_physicalmemory $totalMemoryCapacity = ($memoryInfo | Measure-Object -Property capacity -Sum).sum /1gb $totalMemoryFree = [math]::round(((Get-CIMInstance Win32_OperatingSystem | Measure-Object -Property FreePhysicalMemory -Sum).sum /1024) /1024,2) } catch { throw $_ } try { $healthCheckResultObject | Add-Member -MemberType NoteProperty -Name TotalMemoryCapacity -Value "$totalMemoryCapacity" $healthCheckResultObject | Add-Member -MemberType NoteProperty -Name TotalMemoryFree -Value "$totalMemoryFree" } catch { throw $_ } Write-Verbose "Evalution of system memory complete" Write-Verbose "Evalutating system service.." if ($emfConfig.ServiceName) { try { $systemName = $emfConfig.serviceName $service = Get-CimInstance -ClassName Win32_Service -Filter "Name Like '$systemName'" } catch { throw $_ } if ($service) { try { $healthCheckResultObject | Add-Member -MemberType NoteProperty -Name ServiceState -Value "$($service.State)" $healthCheckResultObject | Add-Member -MemberType NoteProperty -Name ServiceStatus -Value "$($service.Status)" $healthCheckResultObject | Add-Member -MemberType NoteProperty -Name ServiceStartMode -Value "$($service.StartMode)" $healthCheckResultObject | Add-Member -MemberType NoteProperty -Name ServiceProcessId -Value "$($service.ProcessId)" } catch { throw $_ } Write-Verbose "Evalution of system service complete" } else { Write-Warning "Unable to find system service with name $systemName" } } else { Write-Warning "ServiceName from emfConfig is invalid, skipping evalution of system service" } $systemPortFound = $false $systemPropertiesPathFound = $false if (Test-Path "$($emfConfig.SystemRoot)") { $systemPropertiesPath = Get-ChildItem -Path "$($emfConfig.SystemRoot)\*server.xml" -Recurse if ($systemPropertiesPath) { $systemPropertiesPathFound = $true } } if (!($systemPropertiesPathFound)) { if (Test-Path "$($emfConfig.TomcatRoot)") { $systemPropertiesPath = Get-ChildItem -Path "$($emfConfig.TomcatRoot)\*server.xml" -Recurse if ($systemPropertiesPath) { $systemPropertiesPathFound = $true } } } if ($systemPropertiesPathFound) { Write-Verbose "Evalutating ping and database response time.." try { $systemServerXML = Get-Content -Path "$systemPropertiesPath" -Raw $systemServerXML -imatch 'Connector port="(\d{4})" protocol="HTTP.*"' | Out-Null $systemPort = $Matches[1] $systemPortFound = $true } catch { Write-Warning "$($_.Exception)" } if ($systemPortFound) { $systemMonitorUrl = "http://localhost:${systemPort}/monitor/?bypassSSO=true" Write-Verbose "systemMonitorUrl = $systemMonitorUrl" try { $systemStatus = Invoke-WebRequest -Uri "${systemMonitorUrl}&type=alive" -UseBasicParsing -ErrorAction Stop Write-Verbose "Successfully connected to ${systemMonitorUrl}&type=alive" $healthCheckResultObject | Add-Member -MemberType NoteProperty -Name SystemStatusCode -Value "$($systemStatus.StatusCode)" } catch { Write-Verbose "Unable to contact system monitor 'alive'" Write-Verbose "$($_.Exception)" } Write-Verbose "Evalutating database response time.." try { $dbLatency = Invoke-WebRequest -Uri "${systemMonitorUrl}&type=db" -UseBasicParsing -ErrorAction Stop Write-Verbose "Successfully connected to ${systemMonitorUrl}&type=db" if ($dbLatency.StatusCode -eq 200) { $dbLatency.Content -match '1000 times:\s?(.*)\s?ms' | Out-Null [int]$dbResponseTime = $Matches[1] $healthCheckResultObject | Add-Member -MemberType NoteProperty -Name DatabaseResponseTime -Value "$dbResponseTime" } else { Write-Verbose "Unable to query for DB response time" } } catch { Write-Verbose "Unable to contact system monitor 'db'" Write-Verbose "$($_.Exception)" } } else { Write-Warning "Unable to resolve system port" } } else { Write-Warning "Unable to find port for system. Skipping evaluation of ping and database response time" } return $healthCheckResultObject } end { Write-Verbose "$($MyInvocation.MyCommand) completed" } } Export-ModuleMember -Function Invoke-EasitGOHealthCheck function Invoke-EasitGOUpdate { [CmdletBinding(HelpURI="https://github.com/easitab/EasitManagementFramework/blob/main/docs/v1/Invoke-EasitGOUpdate.md")] param ( [Parameter()] [string] $EmfHome = "${env:ALLUSERSPROFILE}\EMF", [Parameter()] [string] $EmfConfigurationFileName = 'emfConfig.xml', [Parameter()] [string] $EmfConfigurationName = 'Dev', [Parameter()] [string] $UpdateResourceDirectory = $null, [Parameter(Mandatory)] [string] $UpdateFilename, [Parameter()] [switch] $RunningElevated, [Parameter()] [switch] $SkipDbBackup, [Parameter()] [switch] $StoredProcedureName ) begin { Write-Verbose "$($MyInvocation.MyCommand) initialized" if (!($RunningElevated)) { throw "Session is not running with elevated priviliges that is need to perfom this action, ensure you are running an elevated session and specify -RunningElevated" } $emfConfig = Get-EMFConfig -EMFHome $EmfHome -ConfigurationFileName $EmfConfigurationFileName -ConfigurationName $EmfConfigurationName } process { if ([string]::IsNullOrWhiteSpace($UpdateResourceDirectory)) { if ([string]::IsNullOrWhiteSpace($emfConfig.UpdateResourceDirectory)) { throw "No path provided as UpdateResourceDirectory. Use -UpdateResourceDirectory or UpdateResourceDirectory in $EmfHome\$EmfConfigurationFileName" } else { $UpdateResourceDirectory = "$($emfConfig.UpdateResourceDirectory)" } } if (Test-Path -Path "$UpdateResourceDirectory") { Write-Verbose "Using $UpdateResourceDirectory as UpdateResourceDirectory" } else { throw "Unable to find $UpdateResourceDirectory" } if ([string]::IsNullOrWhiteSpace($emfConfig.SystemRoot)) { throw "No path provided as SystemRoot. Please update SystemRoot in $EmfHome\$EmfConfigurationFileName for GO" } else { if (!(Test-Path -Path "$($emfConfig.SystemRoot)")) { throw "Unable to find $($emfConfig.SystemRoot)" } else { $systemRoot = "$($emfConfig.SystemRoot)" Write-Verbose "Using systemRoot: $systemRoot" } } if ([string]::IsNullOrWhiteSpace($emfConfig.BackupRoot)) { throw "No path provided as BackupRoot. Please update BackupRoot in $EmfHome\$EmfConfigurationFileName for GO" } else { if (!(Test-Path -Path "$($emfConfig.BackupRoot)")) { try { $backupRootName = Split-Path -Path "$($emfConfig.BackupRoot)" -Leaf $backupRootParent = Split-Path -Path "$($emfConfig.BackupRoot)" -Parent $backupRoot = New-Item -Path $backupRootParent -Name $backupRootName -ItemType Directory } catch { throw $_ } Write-Verbose "Created directory named $backupRootName in $backupRootParent" } else { $backupRoot = "$($emfConfig.BackupRoot)" } } Write-Verbose "Using backupRoot: $backupRoot" $foldersToFind = @('config','logs','webapps') foreach ($folderToFind in $foldersToFind) { $varName = "${folderToFind}Root" if (!(Get-Variable -Name "$varName" -ErrorAction SilentlyContinue)) { New-Variable -Name "$varName" } Set-Variable -Name "$varName" -Value (Get-ChildItem -Path "$systemRoot" -Include "$folderToFind" -Directory -Recurse).Fullname if (!(Get-Variable -Name "$varName" -ValueOnly)) { Set-Variable -Name "$varName" -Value (Get-ChildItem -Path "$systemRoot" -Include "$folderToFind" -Directory -Recurse).Fullname if (!(Get-Variable -Name "$varName" -ValueOnly)) { throw "Unable to find ${varName}" } } $varValue = Get-Variable -Name "$varName" -ValueOnly Write-Verbose "Using ${varName}: $varValue" } try { $systemConfigFile = (Get-ChildItem -Path "$configRoot" -Include 'properties.xml' -File -Recurse).Fullname } catch { throw $_ } if (!($systemConfigFile)) { throw "Unable to find configRoot: $configRoot" } Write-Verbose "Found systemConfigFile: $systemConfigFile" try { $systemProperties = Import-EMFXMLData -Path $systemConfigFile -ReturnAsPSObject } catch { throw $_ } Write-Verbose "Got system properties" try { $warFile = (Get-EasitWarFile -Path "$systemRoot" -Name "$($emfConfig.WarName).war").Fullname } catch { throw $_ } if (!($warFile)) { try { $warFile = (Get-EasitWarFile -Path "$($emfConfig.TomcatRoot)" -Name "$($emfConfig.WarName).war").Fullname } catch { throw $_ } if (!($warFile)) { throw "Unable to find warFile: $warFile" } } Write-Verbose "Using warFile: $warFile" $UpdateFile = Join-Path -Path $UpdateResourceDirectory -ChildPath $UpdateFilename Write-Information "Trying to find update file" -InformationAction Continue if (Test-Path -Path $UpdateFile) { Write-Information "Using UpdateFile: $UpdateFile" -InformationAction Continue } else { throw "Unable to find $UpdateFile" } try { $service = Get-EasitService -ServiceName "$($emfConfig.ServiceName)" Write-Information "Found service $($service.Name)" -InformationAction Continue } catch { throw "Unable to find service for Easit GO" } if (!($SkipDbBackup)) { $rawDbUrl = "$($systemProperties.'dataSource.url')" try { $dbConnectionDetails = Get-DatabaseDetails -Uri $rawDbUrl Write-Verbose $dbConnectionDetails } catch { Write-Verbose $dbConnectionDetails throw "Unable to resolve database connection details" } if ($dbConnectionDetails.supportedProtocol) { Write-Warning "EasitManagementFramework only supports MSSQL at the moment. Perform manual backup of database and specify -SkipDbBackup" break } else { $useLocalCommand = $false if (Get-Command -Module 'SqlServer') { Write-Verbose "Found module SqlServer" $useLocalCommand = $true } else { Write-Verbose "Module SqlServer is not installed on this computer, will attempt to connect to sql server $($dbConnectionDetails.dbServerName)" if (!(Test-NetConnection -ComputerName "$($dbConnectionDetails.dbServerName)" -Port $dbConnectionDetails.dbServerPort)) { throw "Unable to connect to sql server $($dbConnectionDetails.dbServerName) on port $($dbConnectionDetails.dbServerPort), check connection or perform manual backup of database and specify -SkipDbBackup" } Write-Verbose "Successfully connected to sql server $($dbConnectionDetails.dbServerName)" } } } Write-Information "Starting update process for Easit GO" -InformationAction Continue Write-Information "Stopping service" -InformationAction Continue try { $service = Stop-EasitGOApplication -EMFHome $EmfHome -ConfigurationFileName $EmfConfigurationFileName -ConfigurationName $EmfConfigurationName -RunningElevated:$RunningElevated } catch { throw $_ } Write-Information "Service stopped" -InformationAction Continue if ($SkipDbBackup) { Write-Warning "-SkipDbBackup is specified, assuming manual backup of database have been done" } if (!($SkipDbBackup)) { $LASTEXITCODE = 0 $ErrorActionPreference = 'Stop' Write-Information "Attempting to execute stored procedure on database server" -InformationAction Continue if ($useLocalCommand) { if ($dbConnectionDetails.dbInstance) { $serverInstance = "$($dbConnectionDetails.dbServerName)\$($dbConnectionDetails.dbInstance)" } else { $serverInstance = "$($dbConnectionDetails.dbServerName)" } try { Invoke-Sqlcmd -ServerInstance "$serverInstance" -Database "$($dbConnectionDetails.dbName)" -Query "EXEC $StoredProcedureName" -OutputSqlErrors $true } catch { throw $_ } if ($LASTEXITCODE -ne 0) { throw "Invoke-Sqlcmd returned $LASTEXITCODE" } } if (!($useLocalCommand)) { try { $dbSession = New-PSSession -ComputerName "$dbServer" Enter-PSSession -Session $dbSession } catch { throw $_ } Invoke-Sqlcmd -Database "$dbName" -Query "EXEC $StoredProcedureName" -OutputSqlErrors $true -ErrorAction Continue Exit-PSSession Remove-PSSession -Session $dbSession if ($LASTEXITCODE -ne 0) { throw "Invoke-Sqlcmd returned $LASTEXITCODE" } } $ErrorActionPreference = $null $LASTEXITCODE = 0 Write-Information "Backup of database complete" -InformationAction Continue } Write-Information "Perfoming backup action on files and folders" -InformationAction Continue $foldersToBackup = @("$configRoot","$logsRoot","$warFile") foreach ($folder in $foldersToBackup) { try { Backup-EasitFolder -FolderToBackup "$folder" -DestinationFolder $backupRoot } catch { throw $_ } } try { Write-Verbose "Removing $logsRoot" Remove-Item "$logsRoot" -Include '*.*' -Recurse -Force -Confirm:$false -InformationAction SilentlyContinue Write-Verbose "$logsRoot removed" } catch { Write-Warning "$($_.Exception)" } try { Write-Verbose "Removing $warFile" Remove-Item "$warFile" -Confirm:$false -InformationAction SilentlyContinue Write-Verbose "$warFile removed" } catch { Write-Warning "$($_.Exception)" } $expandedWarFolder = Join-Path -Path "$webappsRoot" -ChildPath "$($emfConfig.WarName)" try { Write-Verbose "Removing $expandedWarFolder" Remove-Item "$expandedWarFolder" -Recurse -Force -Confirm:$false -InformationAction SilentlyContinue Write-Verbose "$expandedWarFolder removed" } catch { Write-Warning "$($_.Exception)" } Write-Information "Backup of files and folders have been completed" -InformationAction Continue Write-Information "Updating war file" -InformationAction Continue $newWarToCopy = Join-Path -Path "$($emfConfig.UpdateResourceDirectory)" -ChildPath "$UpdateFilename" Write-Verbose "Looking for $UpdateFilename in $($emfConfig.UpdateResourceDirectory)" if (!(Test-Path -Path $newWarToCopy)) { throw "Unable to find $newWarToCopy. Update can be completed by copying new war ($UpdateFilename) file to $webappsRoot and running Start-EasitGOApplication" } try { Copy-Item -Path "$newWarToCopy" -Destination "$webappsRoot" Get-ChildItem -Path "$webappsRoot\${UpdateFilename}" | Rename-Item -NewName "$($emfConfig.WarName).war" } catch { throw $_ } Write-Information "Starting service" -InformationAction Continue try { $service = Start-EasitGOApplication -EMFHome $EmfHome -ConfigurationFileName $EmfConfigurationFileName -ConfigurationName $EmfConfigurationName -Verify -RunningElevated:$RunningElevated } catch { throw $_ } Write-Information "Update of Easit GO have been completed" -InformationAction Continue } end { Write-Verbose "$($MyInvocation.MyCommand) completed" } } Export-ModuleMember -Function Invoke-EasitGOUpdate function Invoke-Email2GOUpdate { [CmdletBinding(HelpURI="https://github.com/easitab/EasitManagementFramework/blob/main/docs/v1/Invoke-Email2GOUpdate.md")] param ( [Parameter()] [string] $EmfHome = "${env:ALLUSERSPROFILE}\EMF", [Parameter()] [string] $EmfConfigurationFileName = 'emfConfig.xml', [Parameter()] [string] $EmfConfigurationName = 'Email2GO', [Parameter()] [string] $UpdateResourceDirectory = $null, [Parameter(Mandatory)] [string] $UpdateFilename, [Parameter()] [switch] $RunningElevated, [Parameter()] [switch] $Cleanup ) begin { Write-Verbose "$($MyInvocation.MyCommand) initialized" if (!($RunningElevated)) { throw "Session is not running with elevated priviliges that is need to perfom this action, ensure you are running an elevated session and specify -RunningElevated" } $emfConfig = Get-EMFConfig -EMFHome $EmfHome -ConfigurationFileName $EmfConfigurationFileName -ConfigurationName $EmfConfigurationName } process { if ([string]::IsNullOrWhiteSpace($UpdateResourceDirectory)) { if ([string]::IsNullOrWhiteSpace($emfConfig.UpdateResourceDirectory)) { throw "No path provided as UpdateResourceDirectory. Use -UpdateResourceDirectory or UpdateResourceDirectory in $EmfHome\$EmfConfigurationFileName" } else { $UpdateResourceDirectory = "$($emfConfig.UpdateResourceDirectory)" } } if (Test-Path -Path "$UpdateResourceDirectory") { Write-Verbose "Using $UpdateResourceDirectory as UpdateResourceDirectory" } else { throw "Unable to find $UpdateResourceDirectory" } if ([string]::IsNullOrWhiteSpace($emfConfig.SystemRoot)) { throw "No path provided as SystemRoot. Please update SystemRoot in $EmfHome\$EmfConfigurationFileName for Email2GO" } else { if (!(Test-Path -Path "$($emfConfig.SystemRoot)")) { throw "Unable to find $($emfConfig.SystemRoot)" } else { $systemRoot = "$($emfConfig.SystemRoot)" Write-Verbose "Using systemRoot: $systemRoot" } } if ([string]::IsNullOrWhiteSpace($emfConfig.BackupRoot)) { throw "No path provided as BackupRoot. Please update BackupRoot in $EmfHome\$EmfConfigurationFileName for Email2GO" } else { if (!(Test-Path -Path "$($emfConfig.BackupRoot)")) { $backupRootName = Split-Path -Path "$($emfConfig.BackupRoot)" -Leaf $backupRootParent = Split-Path -Path "$($emfConfig.BackupRoot)" -Parent $backupRoot = New-Item -Path $backupRootParent -Name $backupRootName -ItemType Directory Write-Verbose "Created directory named $backupRootName in $backupRootParent" } else { $backupRoot = "$($emfConfig.BackupRoot)" } } Write-Verbose "Using backupRoot: $backupRoot" $configRoot = Join-Path -Path $systemRoot -ChildPath 'config' if (!(Test-Path $configRoot)) { throw "Unable to find configRoot: $configRoot" } else { Write-Verbose "Using configRoot: $configRoot" } $UpdateFile = Join-Path -Path $UpdateResourceDirectory -ChildPath $UpdateFilename $todayMinute = Get-Date -Format "yyyyMMdd_HHmm" Write-Information "Trying to find update file" -InformationAction Continue if (Test-Path -Path $UpdateFile) { if ($UpdateFile -match '\.zip$') { $expandedArchiveFolder = Join-Path -Path $UpdateResourceDirectory -ChildPath "$todayMinute" if (!(Test-Path -Path $expandedArchiveFolder)) { try { Write-Verbose "Creating $expandedArchiveFolder" $expandedArchiveFolder = New-Item -Path $UpdateResourceDirectory -Name $todayMinute -ItemType Directory } catch { throw $_ } } else { try { Write-Verbose "$expandedArchiveFolder already exist, removing files in folder" Get-ChildItem $expandedArchiveFolder | Remove-Item Write-Verbose "Files removed" } catch { throw $_ } } try { Expand-Archive -Path $UpdateFile -DestinationPath $expandedArchiveFolder -InformationAction SilentlyContinue $UpdateFile = (Get-ChildItem -Path $expandedArchiveFolder | Where-Object -Property Name -Like '*.msp').Fullname } catch { throw $_ } } Write-Information "Using UpdateFile: $UpdateFile" -InformationAction Continue } else { throw "Unable to find $UpdateFile" } try { $service = Get-EasitService -ServiceName '%mail2go%' Write-Information "Found service $($service.Name)" -InformationAction Continue } catch { throw "Unable to find service for Email2GO" } Write-Information "Starting update process for Email2GO" -InformationAction Continue Write-Information "Stopping service" -InformationAction Continue try { $service = Set-EasitService -Service $service -Action 'StopService' } catch { throw $_ } Write-Information "Service stopped" -InformationAction Continue $logs = Join-Path -Path $systemRoot -ChildPath 'logs' $email2GOFoldersToBackup = @("$configRoot","$logs") foreach ($folder in $email2GOFoldersToBackup) { try { Backup-EasitFolder -FolderToBackup "$folder" -DestinationFolder $backupRoot -Cleanup $Cleanup } catch { throw $_ } } try { $updateProcess = Start-Process -FilePath $UpdateFile -Wait -PassThru } catch { throw $_ } if ($updateProcess.ExitCode -ne '0') { if ($updateProcess.ExitCode -eq '1602') { Write-Information "Update process terminated" -InformationAction Continue } else { Write-Warning "The update process did not exit (ExitCode: $($updateProcess.ExitCode)) successfully, therefor $($MyInvocation.MyCommand) have been terminated and manual update of Email2GO is needed" } return } try { Get-ChildItem -Path $expandedArchiveFolder | Remove-Item Remove-Item -Path $expandedArchiveFolder Write-Verbose "Removed $expandedArchiveFolder and its contents" } catch { throw $_ } try { $service = Get-EasitService -ServiceName "$($service.Name)" Write-Verbose "Found service $($service.Name)" if ("$($service.State)" -ne 'Running') { Write-Information "Trying to start service $($service.Name)" -InformationAction Continue $service = Set-EasitService -Service $service -Action 'StartService' } else { Write-Verbose "Service $($service.Name) is running" } } catch { throw $_ } Write-Information "Email2GO successfully updated" -InformationAction Continue } end { Write-Verbose "$($MyInvocation.MyCommand) completed" } } Export-ModuleMember -Function Invoke-Email2GOUpdate function New-EMFConfig { [CmdletBinding()] param ( [Parameter()] [Alias('Home')] [string] $EMFHome = "${env:ALLUSERSPROFILE}\EMF", [Parameter()] [Alias('ConfigurationFileName','ConfigFile','ConfigFileName')] [string] $EmfConfigurationFileName = 'emfConfig.xml', [Parameter(Mandatory)] [ValidateSet("Prod","Test","Dev","IntegrationProd","IntegrationTest","IntegrationDev")] [Alias('ConfigurationName','ConfigName')] [string] $EmfConfigurationName, [Parameter(Mandatory)] [Alias('ConfigurationSettings','ConfigSettings')] [hashtable] $EmfConfigurationSettings, [Parameter()] [switch ] $Validate, [Parameter()] [string] $SchemaFile = "$EMFHome\emfConfig.xsd" ) begin { Write-Verbose "$($MyInvocation.MyCommand) initialized" } process { $emfConfigFilePath = "$EMFHome\$EmfConfigurationFileName" if (Test-Path "$emfConfigFilePath") { Write-Verbose -Message "$emfConfigFilePath already exists." try { Get-EMFConfig -EMFHome $EMFHome -EmfConfigurationFileName $EmfConfigurationFileName -EmfConfigurationName $EmfConfigurationName Write-Warning "A configuration with the name $EmfConfigurationName does already exist in $emfConfigFilePath. Use Set-EMFConfig to update configuration!" break } catch { Write-Verbose "No configuration with name $EmfConfigurationName found" } } else { Write-Verbose "$emfConfigFilePath does not exist." if (!(Test-Path -Path $EMFHome)) { New-Item -Path "${env:ALLUSERSPROFILE}" -Name 'EMF' -ItemType Directory Write-Verbose -Message "Created directory EMF in ${env:ALLUSERSPROFILE}" } else { Write-Verbose "Found $EMFHome" } } try { Write-Verbose "Creating xml object for config" $configObject = New-Object System.Xml.XmlDocument [System.Xml.XmlDeclaration] $xmlDeclaration = $configObject.CreateXmlDeclaration("1.0", "UTF-8", $null) $configObject.AppendChild($xmlDeclaration) | Out-Null } catch { Write-Verbose "Failed to create xml object for payload" throw "$_" } try { Write-Verbose "Creating xml element for systems" $configObjectItems = $configObject.CreateElement('systems') $configObject.AppendChild($configObjectItems) | Out-Null } catch { Write-Verbose "Failed to create xml element for systems" throw $_ } try { Write-Verbose "Creating xml element for $EmfConfigurationName" $configObjectItem = $configObject.CreateElement("$EmfConfigurationName") $configObjectItems.AppendChild($configObjectItem) | Out-Null } catch { Write-Verbose "Failed to create xml element for $EmfConfigurationName" throw $_ } foreach ($setting in $ConfigurationSettings.GetEnumerator()) { $settingName = $setting.Name $settingValue = $setting.Value if (!($settingName -eq 'EmfConfigurationName')) { try { Write-Verbose "Creating xml element for setting $settingName" $configObjectItemSetting = $configObject.CreateElement("$settingName") $configObjectItemSetting.InnerText = $settingValue $configObjectItem.AppendChild($configObjectItemSetting) | Out-Null } catch { Write-Verbose "Failed to create xml element for $settingName" throw $_ } } else { Write-Verbose "SettingName = EmfConfigurationName" } } if ($Validate) { $emfConfigFilePathTemp = "$EMFHome\temp.xml" $configObject.Save("$emfConfigFilePathTemp") try { Test-EMFXMLData -Path $emfConfigFilePathTemp -SchemaFile $SchemaFile Test-ConfigurationSetting -XmlObject $configObject Remove-Item $emfConfigFilePathTemp -Force | Out-Null } catch { Remove-Item $emfConfigFilePathTemp -Force | Out-Null throw $_ } } try { $configObject.Save("$emfConfigFilePath") Write-Verbose -Message "Saved config to $emfConfigFilePath" } catch { throw "Unable to save config to $emfConfigFilePath" } } end { Write-Verbose "$($MyInvocation.MyCommand) completed" } } Export-ModuleMember -Function New-EMFConfig function Remove-CertificateFromEasitTrustStore { [CmdletBinding(HelpURI="https://github.com/easitab/EasitManagementFramework/blob/main/docs/v1/Remove-CertificateFromEasitTrustStore.md")] param ( [Parameter(ParameterSetName='LiteralPath',Mandatory=$true)] [string] $LiteralPath, [Parameter(ParameterSetName='Path')] [string] $Path, [Parameter(ParameterSetName='Path',Mandatory=$true)] [string] $TrustStoreName, [Parameter()] [string] $Keytool, [Parameter(Mandatory=$true)] [Alias('keystorepass','truststorepass')] [string] $StorePass, [Parameter(Mandatory=$true)] [string] $CertificateAlias, [Parameter()] [string] $EmfHome = "${env:ALLUSERSPROFILE}\EMF", [Parameter()] [string] $EmfConfigurationFileName = 'emfConfig.xml', [Parameter()] [Alias('system')] [string] $EmfConfigurationName = 'Prod' ) begin { Write-Verbose "$($MyInvocation.MyCommand) initialized" $emfConfig = Get-EMFConfig -EMFHome $EmfHome -ConfigurationFileName $EmfConfigurationFileName -ConfigurationName $EmfConfigurationName } process { if (!($Keytool)) { try { $Keytool = Get-EasitJavaKeytool -Path $emfConfig.EasitRoot Write-Verbose "Keytool = $Keytool" } catch { throw $_ } } if ($Path -and $TrustStoreName) { $trustStorePath = Join-Path -Path $Path -ChildPath $TrustStoreName if (Test-Path $trustStorePath) { Write-Verbose "Using truststore at $trustStorePath" } else { throw "Unable to find $TrustStoreName in $Path" } } if ($Path -and !($TrustStoreName)) { throw "You need to provide a TrustStoreName when specifying Path. Otherwise use LiteralPath." } if ($LiteralPath) { if (Test-Path $LiteralPath) { $trustStorePath = $LiteralPath Write-Verbose "Using truststore at $trustStorePath" } else { throw "Unable to find $LiteralPath" } } if ($StorePass) { if ($CertificateAlias) { Write-Verbose "Executing: $Keytool -delete -alias $CertificateAlias -keystore $trustStorePath -storepass $StorePass" $result = & "$Keytool" -delete -alias "$CertificateAlias" -keystore "$trustStorePath" -storepass "$StorePass" } else { throw "No certificate alias provided" } } else { throw "No storepass provided" } if (!($result)) { break } else { return $result } } end { Write-Verbose "$($MyInvocation.MyCommand) completed" } } Export-ModuleMember -Function Remove-CertificateFromEasitTrustStore function Set-EasitEmailRequestMailboxSetting { [CmdletBinding()] param ( [Parameter()] [string] $EmfHome = "${env:ALLUSERSPROFILE}\EMF", [Parameter()] [string] $EmfConfigurationFileName = 'emfConfig.xml', [Parameter()] [string] $EmfConfigurationName = 'Prod', [Parameter()] [string] $EmailRequestConfigurationFilename = 'config.xml', [Parameter(Mandatory)] [Alias('Mailbox')] [string] $MailboxName, [Parameter(Mandatory)] [Alias('Name')] [string] $SettingName, [Parameter(Mandatory)] [Alias('Value')] [string] $SettingValue ) begin { Write-Verbose "$($MyInvocation.MyCommand) initialized" try { $emfConfig = Get-EMFConfig -Home $EmfHome -ConfigurationFileName $EmfConfigurationFileName -ConfigurationName $EmfConfigurationName Write-Verbose "Found EMF Config" } catch { throw $_ } } process { try { $erXmlConfigFile = Get-ChildItem -Path "$($emfConfig.EmailRequestRoot)" -Include "$EmailRequestConfigurationFilename" -Recurse -Force Write-Verbose "Found ER config." } catch { throw $_ } try { $erConfig = Import-EMFXMLData -Path "$($erXmlConfigFile.FullName)" Write-Verbose "Imported configuration" } catch { throw $_ } try { $node = $erConfig.SelectNodes("//properties/property") | Where-Object {$_.name -eq "displayName"} | Where-Object {$_.value -eq "$MailboxName"} } catch { throw $_ } try { $mailBoxNode = $node.ParentNode.ParentNode Write-Verbose "Found mailbox in configuration" } catch { throw $_ } try { $settingNode = $mailBoxNode.properties.property | Where-Object {$_.name -eq "$SettingName"} } catch { throw $_ } try { $settingNode.Value = "$SettingValue" Write-Verbose "Updated value for $SettingName" } catch { throw $_ } try { $erConfig.Save("$($emfConfig.EmailRequestRoot)\${EmfConfigurationFileName}") Write-Verbose "Saved EmailRequest configuration" } catch { throw $_ } } end { Write-Verbose "$($MyInvocation.MyCommand) completed" } } Export-ModuleMember -Function Set-EasitEmailRequestMailboxSetting function Set-EMFConfig { [CmdletBinding()] param ( [Parameter()] [Alias('Home')] [string] $EMFHome = "${env:ALLUSERSPROFILE}\EMF", [Parameter()] [Alias('ConfigurationFileName','ConfigFile','ConfigFileName')] [string] $EmfConfigurationFileName = 'emfConfig.xml', [Parameter(Mandatory,Position=0)] [Alias('ConfigurationName','ConfigName')] [string] $EmfConfigurationName, [Parameter(Mandatory,ParameterSetName='Manual')] [string] $EasitRoot, [Parameter(ParameterSetName='Manual')] [string] $SystemRoot = "$EasitRoot\Systems\$EmfConfigurationName", [Parameter(ParameterSetName='Manual')] [string] $ServiceName = "Easit$EmfConfigurationName", [Parameter(ParameterSetName='Manual')] [string] $WarName = "ROOT", [Parameter(ParameterSetName='Manual')] [string] $TomcatRoot = "$EasitRoot\Systems\$EmfConfigurationName", [Parameter(ParameterSetName='Manual')] [string] $BackupRoot = "$EasitRoot\_Backup\$EmfConfigurationName", [Parameter(ParameterSetName='Manual')] [Alias('ER','EmailRequest','erRoot')] [string] $EmailRequestRoot = "$EasitRoot\EmailRequest", [Parameter(ParameterSetName='Manual')] [Alias('IC','ImportClient','icRoot')] [string] $ImportClientRoot = "$EasitRoot\ImportClient", [Parameter(ParameterSetName='Manual')] [Alias('urd')] [string] $UpdateResourceDirectory = "$EasitRoot\Update", [Parameter(ParameterSetName='Manual')] [Alias('sbp')] [string] $StoredBackupProcedure = 'StoredBackupProcedureName', [Parameter(Mandatory,ParameterSetName='Array')] [string[]] $PropertySetting, [Parameter()] [switch]$ValidateSettings ) begin { Write-Verbose "$($MyInvocation.MyCommand) initialized" } process { if (Test-Path "$EMFHome\$EmfConfigurationFileName") { Write-Verbose "Located $EMFHome\$EmfConfigurationFileName" try { $currentConfigSettings = Get-EMFConfig -EMFHome $EMFHome -EmfConfigurationFileName $EmfConfigurationFileName -EmfConfigurationName $EmfConfigurationName Write-Verbose "Successfully retrieved configuration" } catch { throw $_ } } else { throw "Cannot find $EMFHome\$EmfConfigurationFileName" } $paramName = $PSCmdlet.ParameterSetName if ($paramName -eq 'Manual') { Write-Verbose "ParameterSetName = $paramName" $configurationSettings = [ordered]@{ EasitRoot = "$EasitRoot" WarName = "$WarName" SystemRoot = "$SystemRoot" ServiceName = "$ServiceName" TomcatRoot = "$TomcatRoot" BackupRoot = "$BackupRoot" EmailRequestRoot = "$EmailRequestRoot" ImportClientRoot = "$ImportClientRoot" UpdateResourceDirectory = "$UpdateResourceDirectory" StoredBackupProcedure = "$StoredBackupProcedure" } Write-Verbose "Created hashtable with settings" } if ($paramName -eq 'Array') { Write-Verbose "ParameterSetName = $paramName" try { foreach ($prop in $PropertySetting) { $tempArray = $prop -split ',' $propName = ($tempArray[0]) -replace ' ', '' $propValue = ($tempArray[1]) -replace ' ', '' $currentConfigSettings | Add-Member -MemberType NoteProperty -Name "$propName" -Value "$propValue" -Force } Write-Verbose "Added new settings to CustomObject" } catch { throw $_ } try { $configurationSettings = [ordered]@{} $currentConfigSettings | Get-Member -Type NoteProperty -ErrorAction Stop | ForEach-Object { $value = $currentConfigSettings."$($_.Name)" $configurationSettings.Add("$($_.Name)", "$value") } } catch { throw $_ } } try { $currentConfigurationFile = New-Object System.Xml.XmlDocument $currentConfigurationFile.Load("$EMFHome\$EmfConfigurationFileName") } catch { Write-Verbose "Something went wrong while loading currentConfigurationFile" throw "$($_.Exception.Message)" } if (!($currentConfigurationFile.systems.${EmfConfigurationName})) { Write-Warning "Unable to find configuration block for $EmfConfigurationName" return } if ($ValidateSettings) { Test-ConfigurationSetting -Hashtable $configurationSettings } try { $configurationSettings.GetEnumerator() | ForEach-Object { $settingName = "$($_.Key)" $settingValue = "$($_.Value)" $currentConfigurationFile.systems.${EmfConfigurationName}.${settingName} = $settingValue } } catch { Write-Warning "$($_.Exception.Message)" } try { $currentConfigurationFile.Save("$EMFHome\$EmfConfigurationFileName") } catch { Write-Verbose "Something went wrong while updating configuration file ($EmfConfigurationFileName), block $EmfConfigurationName" throw $_ } } end { Write-Verbose "$($MyInvocation.MyCommand) completed" } } Export-ModuleMember -Function Set-EMFConfig function Start-EasitGOApplication { [CmdletBinding()] param ( [Parameter()] [string] $EmfHome = "${env:ALLUSERSPROFILE}\EMF", [Parameter()] [Alias('ConfigurationFileName','ConfigFile','ConfigFileName')] [string] $EmfConfigurationFileName = 'emfConfig.xml', [Parameter()] [Alias('ConfigurationName','ConfigName')] [string] $EmfConfigurationName = 'Dev', [Parameter()] [switch] $Verify, [Parameter()] [switch] $RunningElevated ) begin { Write-Verbose "$($MyInvocation.MyCommand) initialized" if (!($RunningElevated)) { throw "Session is not running with elevated priviliges that is need to perfom this action" } try { $emfConfig = Get-EMFConfig -Home $EmfHome -ConfigurationFileName $EmfConfigurationFileName -ConfigurationName $EmfConfigurationName Write-Verbose "Found EMF Config" $easitGoServiceName = "$($emfConfig.ServiceName)" Write-Verbose "ServiceName is $($emfConfig.ServiceName)" } catch { throw $_ } } process { try { $easitGoService = Get-EasitService -ServiceName "$easitGoServiceName" } catch { throw $_ } if ($null -eq $easitGoService) { throw "Unable to find service with name like $easitGoServiceName" } else { Write-Verbose "Successfully got CimInstance for $easitGoServiceName" } Write-Verbose "Starting service $easitGoServiceName" try { $easitGoService = Set-EasitService -Service $easitGoService -Action 'StartService' } catch { throw $_ } Write-Information -Message "Service $easitGoServiceName have been started and is running" -InformationAction Continue if ($Verify) { $verificationFailed = $false Write-Verbose "Trying to verify connectivity" $tomcatConf = (Get-ChildItem -Path "$($emfConfig.SystemRoot)" -Include 'conf' -Directory -Recurse).Fullname if (!($tomcatConf)) { try { $tomcatConf = (Get-ChildItem -Path "$($emfConfig.TomcatRoot)" -Include 'conf' -Directory -Recurse).Fullname } catch { Write-Warning "Unable to find folder conf in $($emfConfig.TomcatRoot)" $verificationFailed = $true } if (!($tomcatConf)) { Write-Warning "Unable to find tomcatConf: $tomcatConf" $verificationFailed = $true } } if (!($verificationFailed)) { if (Test-Path -Path "$tomcatConf") { $tomcatServerXMLPath = (Get-ChildItem -Path "$tomcatConf" -Recurse -Include 'server.xml').FullName if ($tomcatServerXMLPath) { try { $tomcatServerXML = Import-EMFXMLData -Path "$tomcatServerXMLPath" } catch { Write-Warning "Unable to import server.xml, system connectivity not verified" $verificationFailed = $true } $tomcatServerPort = "$($tomcatServerXML.Server.Port)" } else { Write-Warning "Unable to get server.xml from $tomcatConf" $verificationFailed = $true } } else { $verificationFailed = $true } } if (!($verificationFailed)) { Write-Information "Giving the Easit application some time to startup" -InformationAction Continue try { Start-Sleep -Seconds 15 Write-Information "Trying to ping Easit application" -InformationAction Continue $url = "http://localhost:${tomcatServerPort}/monitor/?type=alive" $systemStatus = Invoke-WebRequest -Uri "$url" -UseBasicParsing -ErrorAction Stop } catch { Write-Verbose "$($_.Exception)" } if (!($systemStatus.StatusCode -eq 200)) { Write-Verbose "Web request did not return 200, but $($systemStatus.StatusCode)" $verificationFailed = $true } if ($systemStatus.StatusCode -eq 200) { Write-Information "Connectivity to the Easit application have been verified" -InformationAction Continue $verificationFailed = $false } } if ($verificationFailed) { Write-Information "Unable to verify connectivity to the Easit application" -InformationAction Continue } } return $easitGoService } end { Write-Verbose "$($MyInvocation.MyCommand) completed" } } Export-ModuleMember -Function Start-EasitGOApplication function Stop-EasitGOApplication { [CmdletBinding()] param ( [Parameter()] [string] $EmfHome = "${env:ALLUSERSPROFILE}\EMF", [Parameter()] [Alias('ConfigurationFileName','ConfigFile','ConfigFileName')] [string] $EmfConfigurationFileName = 'emfConfig.xml', [Parameter()] [Alias('ConfigurationName','ConfigName')] [string] $EmfConfigurationName = 'Dev', [Parameter()] [switch] $RunningElevated ) begin { Write-Verbose "$($MyInvocation.MyCommand) initialized" if (!($RunningElevated)) { throw "Session is not running with elevated priviliges that is need to perfom this action" } try { $emfConfig = Get-EMFConfig -Home $EmfHome -ConfigurationFileName $EmfConfigurationFileName -ConfigurationName $EmfConfigurationName Write-Verbose "Found EMF Config" $easitGoServiceName = "$($emfConfig.ServiceName)" Write-Verbose "ServiceName is $($emfConfig.ServiceName)" } catch { throw $_ } } process { try { $easitGoService = Get-EasitService -ServiceName "$easitGoServiceName" } catch { throw $_ } if ($null -eq $easitGoService) { throw "Unable to find service with name like $easitGoServiceName" } else { Write-Verbose "Successfully got CimInstance for $easitGoServiceName" } Write-Verbose "Stopping service $easitGoServiceName" try { $easitGoService = Set-EasitService -Service $easitGoService -Action 'StopService' } catch { throw $_ } Write-Verbose "Service $easitGoServiceName have been stopped" } end { Write-Verbose "$($MyInvocation.MyCommand) completed" } } Export-ModuleMember -Function Stop-EasitGOApplication function Test-EMFXMLData { [CmdletBinding()] param ( [Parameter()] [Alias('Home')] [string] $EMFHome = "${env:ALLUSERSPROFILE}\EMF", [Parameter()] [string] $Path = "$EMFHome\emfConfig.xml", [Parameter()] [string] $SchemaFile = "$EMFHome\emfConfig.xsd", [Parameter()] [switch]$ValidateSettings ) begin { Write-Verbose "$($MyInvocation.MyCommand) initialized" } process { if (Test-Path $Path) { Write-Verbose "Found $Path" } else { Write-Verbose "Unable to find $Path" } if (Test-Path $SchemaFile) { Write-Verbose "Found $SchemaFile" } else { throw $_ } [scriptblock] $ValidationEventHandler = { Write-Error $args[1].Exception.InnerExceptionMessage } $schemaReader = New-Object System.Xml.XmlTextReader $SchemaFile $schema = [System.Xml.Schema.XmlSchema]::Read($schemaReader, $ValidationEventHandler) $xml = New-Object System.Xml.XmlDocument Write-Verbose 'Created XML-object' try { $xml.Schemas.Add($schema) | Out-Null Write-Verbose 'Added schema to XML-object' } catch { $schemaReader.Close() throw $_ } try { $xml.Load($Path) Write-Verbose 'Loaded XML-file to XML-object' } catch { $schemaReader.Close() throw $_ } try { Write-Verbose "Validating $Path against $SchemaFile" $xml.Validate({ throw ($Exception = $args[1].Exception) }) Write-Verbose "XML validate without errors" } catch { $schemaReader.Close() throw $_ } if ($ValidateSettings) { Test-ConfigurationSetting -XmlObject $xml } Write-Information "Configuration file ($Path) validation OK against $SchemaFile" -InformationAction Continue return } end { $schemaReader.Close() Write-Verbose "$($MyInvocation.MyCommand) completed" } } Export-ModuleMember -Function Test-EMFXMLData |