Greyhound.psm1

function Get-GreyhoundInstallLocation {
    $GreyhoundInstallLocation = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Greyhound' -Name InstallLocation).InstallLocation
    if (Test-Path $GreyhoundInstallLocation) {
        $GreyhoundInstallLocation
    } else {
        Write-Host 'Es wurde kein Installationspfad für GREYHOUND gefunden.'
    } 
}



function Get-GreyhoundVersionInfo {
    $GreyhoundServerExe = (Get-GreyhoundInstallLocation) + 'Server\GreyhoundServer.exe'
    if (Test-Path -Path $GreyhoundServerExe) {
        $Version = (Get-Item $GreyhoundServerExe).VersionInfo.ProductVersionRaw
        $Version
    } else {
        Write-Error "GREYHOUND ist nicht installiert." -Category ObjectNotFound
        Break
    }
}



function Invoke-GreyhoundAdmin {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$false)]
        [Switch]$Start,
        [Switch]$Stop
    )
   
    try {
        $GreyhoundAdmin = (Get-GreyhoundInstallLocation) + 'Server\GreyhoundAdmin.exe'
        if (!(Test-Path $GreyhoundAdmin)) {
            Throw "Der GREYHOUND Admin wurde nicht gefunden."
        }

        if ($Start) {
            if ((Start-Process -FilePath "$GreyhoundAdmin" -ArgumentList "-Start -NoGui" -Wait -NoNewWindow -PassThru).Exitcode -gt 0) {
                Throw "Der GREYHOUND Admin hat einen ExitCode ausgegeben"
            }
        } elseif ($Stop) {
            if ((Start-Process -FilePath "$GreyhoundAdmin" -ArgumentList "-Stop -NoGui" -Wait -NoNewWindow -PassThru).Exitcode -gt 0) {
                Throw "Der GREYHOUND Admin hat einen ExitCode ausgegeben"
            }
        }

    }
    catch {
        Write-Host $($PSItem.ToString())
    }
}



function Restart-GreyhoundServer {
    Invoke-GreyhoundAdmin -Stop
    Invoke-GreyhoundAdmin -Start
}



function Get-GreyhoundSystemPassword {
    $GreyhoundServerIni = (Get-GreyhoundInstallLocation) + 'Server\GreyhoundServer.ini'
    if (Test-Path $GreyhoundServerIni) {
        $GreyhoundSystemPassword = (Get-Content $GreyhoundServerIni | Select-String -Pattern 'SystemPassword' -SimpleMatch | ConvertFrom-StringData).SystemPassword
        $GreyhoundSystemPassword
    } else {
        Write-Host 'Die GREYHOUND Serverkonfiguration ´"' $GreyhoundServerIni '´" wurde nicht gefunden.'
    }
}



function Get-GreyhoundServerIniValue {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$false)]
        [String]$Key
    )

    $GreyhoundServerIni = (Get-GreyhoundInstallLocation) + 'Server\GreyhoundServer.ini'
    if (Test-Path $GreyhoundServerIni) {
        if (!$Key) {
            $Result = Get-Content $GreyhoundServerIni
        } else {
            $Result = (Get-Content $GreyhoundServerIni | Select-String "^$Key=" | ConvertFrom-StringData).$Key
        }
        $Result
    } else {
        Write-Host 'Die GREYHOUND Serverkonfiguration ´"' $GreyhoundServerIni '´" wurde nicht gefunden.'
    }
}


# function Get-GreyhoundServerInfo {
<#
.SYNOPSIS
    Gets information from the GREYHOUND Server
.DESCRIPTION
    Long description
.EXAMPLE
    Example of how to use this cmdlet
#>


<#
[CmdletBinding(DefaultParameterSetName='Parameter Set 1'
    )]
 
    Param (
        [Parameter(
        Mandatory=$false,
        ParameterSetName='Parameter Set 1')]
 
 
        [Parameter(
        Mandatory=$false,
        ParameterSetName='Parameter Set 2')]
 
        [string]$Hostname = 'localhost',
        [string]$Username = 'system',
        [string]$Password = (Get-GreyhoundSystemPassword),
        [Boolean]$UseSsl = $true,
        [Int32]$Port = '443'
    )
 
    if ($UseSsl) {
        $GreyhoundServerUri = 'https://' + $Hostname + ':' + $Port + '/json'
    } else {
        $GreyhoundServerUri = 'http://' + $Hostname + ':' + $Port + '/json'
    }
 
    $ContentType = 'application/json'
    $UserAgent = 'PowerShell'
    $Body = '{"version":"1.1", "method": "RpcInfo.GetServerInfo", "params": [true]}'
 
    $RandomStr = (Get-Random).ToString()
    $Md5 = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
    $Utf8 = New-Object -TypeName System.Text.UTF8Encoding
    $ClientID = ([System.BitConverter]::ToString($Md5.ComputeHash($Utf8.GetBytes($RandomStr)))).Replace('-', '')
 
    # $Username = 'system'
    # $Password = Get-GreyhoundSystemPassword
    $Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f ($ClientID + '-' + $Username) ,$Password)))
 
    Write-Host @"
        "$GreyhoundServerUri" $GreyhoundServerUri
        '$RandomStr' $RandomStr
        '$Md5' $Md5
        '$Utf8' $Utf8
        '$ClientID + $Username' + ($ClientID + '-' + $Username)
        '$Authorization' + $Authorization
"@ `
        -ForegroundColor Yellow
 
 
    #try {
        $GreyhoundResponse = Invoke-RestMethod -Method Post -UserAgent $UserAgent -ContentType $ContentType -Uri $GreyhoundServerUri -Body $Body -Headers @{Authorization=($Authorization)}
 
        Write-Host '$GreyhoundResponse' ($GreyhoundResponse)
        write-host '$GreyhoundResponse.Error' ($GreyhoundResponse.Error)
        Write-Host '$GreyhoundResponse.Result' ($GreyhoundResponse.Result)
 
        if ((!$GreyhoundResponse).Error) {
            return $GreyhoundResponse.Result
        } else {
            return $GreyhoundResponse.Error.message
        }
       $GreyhoundResult
    #} catch {
        #Write-Host 'Es ist ein Fehler bei der Abfrage des GREYHOUND Servers an' $GreyhoundServerUri 'aufgetreten.'
    #}
}
#>


#function Get-ApplianceDataXml {
<#
.SYNOPSIS
    Gets individual Appliance configuration data from GREYHOUND Control Center (GCC)
.DESCRIPTION
    Long description
.EXAMPLE
    Example of how to use this cmdlet
#>


<#
    [CmdletBinding(DefaultParameterSetName='Parameter Set 1',
                   SupportsShouldProcess=$true,
                   PositionalBinding=$false,
                   HelpUri = '',
                   ConfirmImpact='')]
    [Alias()]
    Param (
        # Param1 help description
        [Parameter(Mandatory=$false,
                   Position=0,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true,
                   ValueFromRemainingArguments=$false,
                   ParameterSetName='Parameter Set 1')]
        [AllowEmptyString()]
        [string]$ApplianceKey,
         
        # Param2 help description
        [Parameter(Mandatory=$true,
                   Position=1,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true,
                   ValueFromRemainingArguments=$false)]
        [string[]]$ApplianceSerialNumbers
    )
     
    $GccUri = 'https://greyhound-software.com/gcc/xmlrpc/'
    $ContentType = 'application/xml'
   
    for ($i=0; $i -lt $ApplianceSerialNumbers.Count; $i++) {$SerialValues = $SerialValues + "<value>" + $ApplianceSerialNumbers[$i] + "</value> "}
 
    $Body = "<?xml version=`"1.0`" encoding=`"UTF-8`"?>
    <methodCall>
        <methodName>GetApplianceData</methodName>
        <params>
            <param>
                <value>
                    <array>
                        <data>
                            " + $SerialValues + "
                        </data>
                    </array>
                </value>
            </param>
            <param>
                <value>
                    <string>" + $ApplianceKey + "</string>
                </value>
            </param>
        </params>
    </methodCall>"
 
    #Write-Host "`$Body = '$Body'" -ForegroundColor Yellow
 
    $GccResult = Invoke-RestMethod -Uri $GccUri -Method Post -Body $Body -ContentType $ContentType
 
    try
    {
        $FaultString = $GccResult.methodResponse.fault.value.struct.member[1].value.string
    }
    catch
    {}
 
    $GccValues = $GccResult.methodResponse.params.param.value.struct.member
 
    if (!$FaultString) {
 
        $NewObject = New-Object -TypeName psobject
 
        # Alle Daten außer ProductKeys speichern
        $GccValues | Where-Object Name -ne ProductKeys | ForEach-Object -Process {Add-Member -InputObject $NewObject -MemberType NoteProperty -Name $_.Name -Value $_.Value.InnerText -Force}
 
        # ProductKeys aus Array ermitteln und speichern
        $ProductKeyValues = ($GccValues | Where-Object Name -eq ProductKeys).value.array.data.value.struct.member
 
        Write-Host $ProductKeyValues
 
        if ($ProductKeyValues) {
            for ($i=0; $i -le ($ProductKeyValues | Measure-Command).Count - 1; $i++) {
 
                if ($ProductKeyValues.name[$i] -eq 'Name' -and $ProductKeyValues.name[$i+1] -eq 'ProductKey')
 
                {
                    $NewObject | Add-Member -NotePropertyName $ProductKeyValues.value[$i].string -NotePropertyValue $ProductKeyValues.value[$i+1].string
                }
 
            }
        } else {
            Write-Host 'Es wurden keine Productkeys gefunden.'
        }
 
 
    } else {
 
        Write-Host 'GCC-Antwort:' $FaultString -ForegroundColor Red
    }
 
return $NewObject
 
}
#>




function Get-ApplianceSerialNumbers {
<#
.SYNOPSIS
    Gets the serial numbers of installed harddrives, memory chips and motherboard
.DESCRIPTION
    Long description
.EXAMPLE
    Example of how to use this cmdlet
#>


    # Seriennummern aller Laufwerke ermitteln
    Get-CimInstance CIM_DiskDrive | Select-Object SerialNumber | ForEach-Object -Process {$ApplianceSerialNumbers += @($_.SerialNumber)}
    # Seriennummern aller RAM-Chips ermitteln
    Get-CimInstance CIM_Chip | Select-Object SerialNumber | ForEach-Object -Process {$ApplianceSerialNumbers += @($_.SerialNumber)}
    # Seriennummer des Motherboards ermitteln
    Get-CimInstance CIM_BIOSElement | Select-Object SerialNumber| ForEach-Object -Process {$ApplianceSerialNumbers += @($_.SerialNumber)}

    $ApplianceSerialNumbers 
    
}


function New-GreyhoundVM {
    [CmdletBinding()]
    Param (
        # Just some help
        [Parameter(Mandatory=$true)]
        [String]$VmName,

        [Parameter(Mandatory=$false)]
        [String]$VmNotes,
        [String]$VmSwitchName = (Get-VMSwitch | Where-Object SwitchType -eq External)[0].Name,
        [Int64]$VmVHDSize = 64GB,
        [String]$VHDPath,
        [String]$VmBasePath = (Get-VMHost).VirtualMachinePath + '\' + $VmName,
        [Int]$VmGeneration = 2,
        [Int]$VMProcessorCount = 4,
        [Int64]$VmMemoryStartupBytes = 4GB,
        [Int64]$VmMemoryMinimumBytes = 4GB,
        [Int64]$VMMemoryMaximumBytes = 8GB
    )

    if (!$VHDPath) {
        # Vm mit neuer VHD erstellen falls keine VHD angegeben wurde
        $VHDPath + '.vhdx'
        New-VM -Name $VmName -Generation $VmGeneration -SwitchName $VmSwitchName -NewVHDPath $VHDPath -NewVHDSizeBytes $VmVHDSize |
            Set-VM -ProcessorCount $VMProcessorCount -DynamicMemory -MemoryStartupBytes $VmMemoryStartupBytes -MemoryMinimumBytes $VmMemoryMinimumBytes -MemoryMaximumBytes $VMMemoryMaximumBytes -Notes $VmNotes -Passthru |
            Move-VMStorage -DestinationStoragePath $VmBasePath

    } else {
        # Vm mit angegebener VHD erstellen
        if (Test-Path $VHDPath) {
            New-VM -Name $VmName -Generation $VmGeneration -SwitchName $VmSwitchName -VHDPath $VHDPath |
                Set-VM -ProcessorCount $VMProcessorCount -DynamicMemory -MemoryStartupBytes $VmMemoryStartupBytes -MemoryMinimumBytes $VmMemoryMinimumBytes -MemoryMaximumBytes $VMMemoryMaximumBytes -Notes $VmNotes -Passthru |
                Move-VMStorage -DestinationStoragePath $VmBasePath
        } else {
            Write-Error 'Der Pfad zur VHD-Datei ist ungültig.'
        }
    }

    # Add Windows Iso
    #Add-VMDvdDrive -VMName $VmName -Path C:\Hyper-V\_ISOs\14393.0.161119-1705.RS1_REFRESH_SERVER_EVAL_X64FRE_DE-DE.ISO-updated.iso

    # Change boot order to boot from windows iso
    #Set-VMFirmware -VMName $VmName -FirstBootDevice (Get-VMDvdDrive -VMName $VmName)

}



function Get-MariaDBSetup {
    [CmdletBinding()]
    param (
        [string]$DownloadDir=$PWD.Path,
        [string]$BaseUrl = 'https://greyhound-software.com/files/greyhound',
        [string]$SetupName = 'MariaDBSetup.msi',
        [switch]$Force = $false
    )

    try {
        $SourceFile = $SourceFile = "$BaseUrl/$SetupName"
        $DestinationFile = $DownloadDir.TrimEnd('\') + '\' + $SetupName

        if ((Test-Path $DestinationFile) -and (!$Force)) {
            Write-Host "Es ist bereits eine Datei mit '$DestinationFile' vorhanden."
            Break
        } else {
            Start-BitsTransfer -Source $SourceFile -Destination $DestinationFile -Description "Downloading $SourceFile"
        }

        if (Test-Path $DestinationFile) {
            $DestinationFile
        } else {
            Throw "Es ist ein Fehler beim Herunterladen der Datei '$SourceFile' aufgetreten."
        }
    }
    catch {
        Write-Error $($PSItem.ToString()) -Category ObjectNotFound
    } 
}



function Get-GreyhoundServerSetup {
    [CmdletBinding()]
    param (
        [string]$DownloadDir=$PWD.Path,
        [string]$BaseUrl = 'https://greyhound-software.com/files/greyhound',
        [string]$SetupBaseName = 'GreyhoundSetup',
        [switch]$Beta,
        [switch]$Test
    )

    try {
        if ($Beta) {
            $SetupName = "${SetupBaseName}Beta.exe"
        } elseif ($Test) {
            $SetupName = "${SetupBaseName}Test.exe"
        } else {
            $SetupName = "${SetupBaseName}.exe"
        }
    
        $SourceFile = "$BaseUrl/$SetupName"
        $DestinationFile = $DownloadDir.TrimEnd('\') + '\' + $SetupName
    
        if ((Test-Path $DestinationFile) -and (!$Force)) {
            Write-Host "Es ist bereits eine Datei mit '$DestinationFile' vorhanden."
            Break
        } else {
            Start-BitsTransfer -Source $SourceFile -Destination $DestinationFile -Description "Downloading $SourceFile"
        }
    
        if (Test-Path $DestinationFile) {
            $DestinationFile
        } else {
            Throw "Es ist ein Fehler beim Herunterladen der Datei '$SourceFile' aufgetreten."
        }
           
    }
    catch {
        Write-Error $($PSItem.ToString()) -Category ObjectNotFound
    }
    
}



function Get-GreyhoundWim {
    [CmdletBinding()]
    param (
        $Url = 'https://greyhound-software.com/files/greyhound/tools/GreyhoundServer.wim',
        $DownloadDir = $env:TEMP,
        [switch]$Force
    )

    $ImageName = $Url.Substring($Url.LastIndexOf('/') + 1)
    $ImageFile = "$DownloadDir\$ImageName"

    if (Test-Path $ImageFile) {
        if ($Force) {
            Start-BitsTransfer -Source $Url -Destination $ImageFile -Description "Downloading $ImageName ..."
        } else {
            Write-Information "Die Datei '$ImageFile' ist bereits vorhanden. -Force benutzen um diese zu überschreiben."
            Return $ImageFile
        }
    } else {
        Start-BitsTransfer -Source $Url -Destination $ImageFile -Description "Downloading $ImageName ..."
    }

    if (Test-Path $ImageFile) {
        Return $ImageFile
    } else {
        Write-Error "Es ist ein Fehler beim Herunterladen der Datei '$Url' aufgetreten."
    }    
}



function Install-MariaDB {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$true,
        ValueFromPipeline)]
        [String]$SetupFile,
        [Parameter(Mandatory=$false)]
        [String]$ServiceName='MySql',
        [Boolean]$AllowRemoteRootAccess,
        [Boolean]$SkipNetworking,
        [String]$Password
    )

    $SetupFile = Resolve-Path($SetupFile)
    if (!(Test-Path -Path $SetupFile)) {
        Write-Error "Die Datei '$SetupFile' wurde nicht gefunden." -Category ObjectNotFound
        Break
    }

    $Command = (Get-Command 'msiexec').Path
    $Arguments = @(
        "/package",
        "`"$SetupFile`"",
        "SERVICENAME=$ServiceName",
        "/qn"
    )

    if ($Password) {
        $Arguments += @("PASSWORD=$Password")
    }

    if ($AllowRemoteRootAccess) {
        $Arguments += @("ALLOWREMOTEROOTACCESS=True")
    } else {
        $Arguments += @("ALLOWREMOTEROOTACCESS=False")
    }

    Write-Host 'Die Datei' $SetupFile 'wird installiert...'

    try {
        $CommandBasename = $Command.Substring($Command.LastIndexOf('\') + 1, $Command.LastIndexOf('.') - $Command.LastIndexOf('\') - 1)
        $StdOutFile = "$env:TEMP\$CommandBasename.stdout"
        $StdErrFile = "$env:TEMP\$CommandBasename.stderr"

        if ((Start-Process -FilePath "$Command" -ArgumentList "$Arguments" -RedirectStandardOutput $StdOutFile -RedirectStandardError $StdErrFile -Wait -PassThru).ExitCode -eq 0) {
            Get-Content $StdOutFile
        } else {
            (Get-Content $StdErrFile)
            Throw "Es ist ein Fehler bei der Installation aufgetreten. StdOut: " + (Get-Content $StdErrFile)
        }
    } catch {
        Write-Error "Es ist ein Fehler bei der Ausführung des Befehls '$Command $Arguments' aufgetreten: $($PSItem.ToString())"
    }
    finally {
        Remove-Item $StdOutFile -Force -ErrorAction SilentlyContinue
        Remove-Item $StdErrFile -Force -ErrorAction SilentlyContinue 
    }
}



function Install-GreyhoundServer {
    [CmdletBinding()]
    [Alias("Update-GreyhoundServer")]
    param (
        [Parameter(Mandatory=$true,
        ValueFromPipeline)]
        [String]$SetupFile,
        [Parameter(Mandatory=$false)]
        [String]$ContractNo,
        [String]$SerialNo,
        [ValidateSet('Complete', 'Server', 'Client')][String]$Kind='Server',
        [String]$TargetDir="$ENV:ProgramData\GREYHOUND\",
        [Switch]$DesktopShortcut=$false,
        [Switch]$StartMenuShortcut=$false,
        [Switch]$QuicklaunchShortcut=$false,
        [Switch]$DefaultMailClient=$false,
        [Switch]$PrinterDriver=$false,
        [Switch]$AutoStart=$false,
        [String]$DatabaseUser='root',
        [String]$DatabasePass='root',
        [int16]$DatabasePort=3306,
        [ValidateSet('Small', 'Medium', 'Large')][String]$DatabaseTemlate='Large',
        [String]$AdminPassword='admin',
        [Switch]$Force=$false
    )

    try {
        $SetupMode = ''

        $SetupFile = Resolve-Path($SetupFile)
        if (Test-Path -Path $SetupFile) {
            $Command = $SetupFile
        } else {
            Write-Error "Die Datei '$SetupFile' wurde nicht gefunden." -Category ObjectNotFound
            Break
        }

        if (Get-GreyhoundInstallLocation) {
            $SetupMode = 'Update'
            try {
                $InstalledVersion = Get-GreyhoundVersionInfo
                $SetupVersion = (Get-Item $SetupFile).VersionInfo.ProductVersionRaw

                if ($InstalledVersion.Revision -gt $SetupVersion.Revision) {
                    Write-Host "Die installierte Version $InstalledVersion ist neuer als die Installationsdatei $SetupVersion" 
                    if (!($Force)) {
                        Break
                    }
                } elseif ($InstalledVersion.Revision -eq $SetupVersion.Revision) {
                    Write-Host "Es ist bereits die Version $InstalledVersion installiert." 
                    if (!($Force)) {
                        Break
                    }
                }
    
                [String]$ContractNo = Get-GreyhoundServerIniValue 'ContractNumber'
                [String]$SerialNo = Get-GreyhoundServerIniValue 'Serial'  
    
                $Arguments = @(
                    "-silent",
                    "-contract", "$ContractNo",
                    "-serial", "$SerialNo",
                    "-kind", "$Kind"
                )                  
            }
            catch {
                Write-Error "Es ist ein Fehler bei der Versionsermittlung aufgetreten."
            }
        } else {
            $SetupMode = 'Install'
            $Arguments = @(
                "-silent",
                "-contract", "$ContractNo",
                "-serial", "$SerialNo",
                "-kind", "$Kind",
                "-targetdir", "$TargetDir",
                "-databaseuser", "$DatabaseUser",
                "-databasepass", "$DatabasePass",
                "-databaseport", "$DatabasePort"
                "-databasetemplate", "$DatabaseTemlate",
                "-adminpassword", "$AdminPassword"
            )

            if (!$AutoStart) {
                $Arguments += @("-nostart")
            }

            if (!$DesktopShortcut) {
                $Arguments += @("-nodesktop")
            }

            if (!$StartMenuShortcut) {
                $Arguments += @("-nostartmenu")
            }

            if (!$QuicklaunchShortcut) {
                $Arguments += @("-noquicklaunch")
            }

            if (!$DefaultMailClient) {
                $Arguments += @("-nodefaultmail")
            }

            if (!$PrinterDriver) {
                $Arguments += @("-noprinterdriver")
            }
        }

        if (!($ContractNo -and $SerialNumber)) {
            if ($SetupMode -eq 'Install') {
                Write-Host "GREYHOUND wird installiert..."
            } else {
                $VersionInstalled = (Get-GreyhoundVersionInfo).ToString()
                Write-Host "Die GREYHOUND-Installation" $VersionInstalled "wird aktualisiert..."
            }
 
            if ((Start-Process -FilePath "$Command" -ArgumentList "$Arguments" -Wait -PassThru).ExitCode -eq 0) {
                Write-Host "Die GREYHOUND-Installation war erfolgreich."
            } else {
                Throw "Das GREYHOUND-Setup hat einen unbekannten Fehler gemeldet."
            }
        } else {
            Write-Error "Fuer eine Installation oder ein Update sind eine Vertragsnummer und eine Seriennummer notwendig." -Category NotSpecified
            Break
        }
    }
    catch {
        Write-Error "Es ist ein Fehler bei der GREYHOUND-Installation aufgetreten: $($PSItem.ToString())"
    }
}



function New-GreyhoundDatabaseDump {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$false,
        ValueFromPipeline)]
        [string]$MySqlUser='root',
        [string]$MySqlPassword='',
        [string]$MySqlParameters='--default-character-set=latin1',
        [string]$MySqlDatabase='greyhound',
        [switch]$Compress,
        [string]$DestinationPath=$PWD.Path
    )

    $MySqlInstallPath = (Get-ChildItem 'C:\Program Files\Maria*').FullName
    $MySqlDump= $MySqlInstallPath + '\bin\mysqldump.exe'
    $StdErr = $env:TEMP + '\mysql.stderr'
        
    if (!(Test-Path -Path $MySqlDump)) {
        Write-Warning 'Die Exe-Datei' $MySqlDump 'wurde nicht gefunden.'
        Break
    }

    $MySqlDumpArgs = @(
        "--user=$MySqlUser"
    )

    if ($MySqlPassword) {
        $MySqlDumpArgs += @(
            "--password=$MySqlPassword"
        )
    }
    
    $MySqlDumpArgs += @(
        "--default-character-set=latin1",
        "$MySqlDatabase"
    )

    try {
        [string]$SqlFile = $DestinationPath + '\' + $MySqlDatabase + '.sql'
        if ((Start-Process -FilePath $MySqlDump -ArgumentList $MySqlDumpArgs -RedirectStandardOutput $SqlFile -RedirectStandardError $StdErr -Wait -NoNewWindow -PassThru).Exitcode -gt 0) {
            if (Test-Path -Path $StdErr) {
                $ExceptionText = Get-Content $StdErr
                Remove-Item $StdErr
            }
            Throw $ExceptionText
        } else {
            Write-Host $SqlFile
        }
    }
    catch {
        Write-Host $($PSItem.ToString())
        Remove-Item $SqlFile
        Break 
    }

    if ($Compress) {
        if (Test-Path -Path $SqlFile) {
            $Zip = (Get-Item  $SqlFile).DirectoryName + '\' + (Get-Item  $SqlFile).BaseName + '.zip'
            if (Test-Path -Path $Zip) {
                Remove-Item $Zip
            }
            
            try {
                Write-Verbose "Der Datenbank-Dump wird komprimiert. Ziel: $Zip"
                Compress-Archive -Path $SqlFile -DestinationPath $Zip -CompressionLevel Optimal
            }
            catch {
                Write-Error "Es ist ein Fehler beim Komprimieren des Datenbank-Dumps aufgetreten."
            }
            finally {
                Write-Verbose "Die Datei $SqlFile wird gelöscht."
                Remove-Item $SqlFile 
            }

        } else {
            Write-Warning "Die Datenbank-Datei $SqlFile konnte nicht komprimiert werden, weil sie nicht vorhanden ist."
        }
    }
}



function Invoke-MySqlQuery {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$true)]
        [string]$MySqlQuery,
        [Parameter(Mandatory=$false)]
        [string]$MySqlHostname='localhost',
        [string]$MySqlUser='root',
        [string]$MySqlPass=''
    )

    $MySqlInstallPath = (Get-ChildItem 'C:\Program Files\Maria*').FullName
    $Exe = $MySqlInstallPath + '\bin\mysql.exe'
    
    if (!(Test-Path -Path $Exe)) {
        Write-Warning 'Die Exe-Datei' $Exe 'wurde nicht gefunden.'
        Break
    }

    $Arguments = @(
        "--host=$MySqlHostname"
        "--user=$MySqlUser"
        '--execute="' + $MySqlQuery + '"'
    )

    if ($MySqlPass) {
        $Arguments += @(
            "--password=$MySqlPass"
        )
    }
    
    try {
        $ExeBasename = $Exe.Substring($Exe.LastIndexOf('\') + 1, $Exe.LastIndexOf('.') - $Exe.LastIndexOf('\') - 1)
        $StdOut = $env:TEMP + $ExeBasename + '.stdout'
        $StdErr = $env:TEMP + $ExeBasename + '.stderr'
    
        Start-Process -FilePath "$Exe" -ArgumentList "$Arguments" -Wait -RedirectStandardOutput $StdOut -RedirectStandardError $StdErr -NoNewWindow
        if (Test-Path -Path $StdOut) {
            Get-Content $StdOut
        }
        if (Test-Path -Path $StdErr) {
            Get-Content $StdErr
        }           
    }
    finally {
        Remove-Item $StdOut -Force
        Remove-Item $StdErr -Force      
    }
}



function Remove-GreyhoundDatabase {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$false,
        ValueFromPipeline)]
        [string]$MySqlHostname='localhost',
        [string]$MySqlUser='root',
        [string]$MySqlPass=''
    )

    $Query = 'DROP DATABASE greyhound;'

    Invoke-MySqlQuery -Query $Query -MySqlHostname $MySqlHostname -MySqlUser $MySqlUser -MySqlPass $MySqlPass
}



<#
function Start-GreyhoundServerTransfer {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$true,
        ValueFromPipeline)]
        [String]$Path,
        [String]$Destination
    )
 
    if (!(Test-Path $Path)) {
        Write-Host "Der Quellpfad '$Path' existiert nicht."
        Break
    }
    if (!(Test-Path $Destination)) {
        Write-Host "Der Zielpfad '$Destination' existiert nicht."
        Break
    }
 
    $RcSource = $Path.TrimEnd('\')
    $RcDestination = $Destination.TrimEnd('\')
    $RcExclusionFiles = @("*.bak", "*.exe", "*.dll", "*.log", "*.txt", "*.ini", "*.eml")
    $RcExclusionDirs = @("Antispam", "ItemCount", "Keys", "Logs", "MariaDB", "MonitorLogs", "MySQL", "Plugins", "Temp", "Updates")
    $RcOptions = @("/NODCOPY", "/MIR", "/NP", "/R:5", "/W:15", "/MT:16", "/XF $RcExclusionFiles", "/XD $RcExclusionDirs")
 
    $RcArgumentList = @(
        "`"$RcSource`"",
        "`"$RcDestination`"",
        "$RcOptions"
    )
 
    Start-Process -FilePath robocopy -ArgumentList $RcArgumentList -Wait -NoNewWindow
}
#>