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 Stop-GreyhoundServer {
    $GreyhoundAdmin = (Get-GreyhoundInstallLocation) + 'Server\GreyhoundAdmin.exe'
    if (Test-Path $GreyhoundAdmin) {
        & $GreyhoundAdmin -Stop
        #$GreyhoundAdmin
     } else {
        Write-Host ('Der GREYHOUND Admin ist nicht installiert.')
    }
}


function Start-GreyhoundServer {
    $GreyhoundAdmin = (Get-GreyhoundInstallLocation) + 'Server\GreyhoundAdmin.exe'
    if (Test-Path $GreyhoundAdmin) {
        & $GreyhoundAdmin -Start
        #$GreyhoundAdmin
     } else {
        Write-Host ('Der GREYHOUND Admin ist nicht installiert.')
    }
}


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


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-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]$VmVHDName,
        [String]$VmBasePath = (Get-VMHost).VirtualMachinePath + '\' + $VmName,
        [Int]$VmGeneration = 2,
        [Int]$VMProcessorCount = 4,
        [Int64]$VmMemoryStartupBytes = 4GB,
        [Int64]$VmMemoryMinimumBytes = 4GB,
        [Int64]$VMMemoryMaximumBytes = 8GB
    )

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

    }

    # 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 (
        $SetupUrl = 'https://greyhound-software.com/files/greyhound/MariaDBSetup.msi',
        $DownloadDir = $env:TEMP
    )

    $SetupName = $SetupUrl.Substring($SetupUrl.LastIndexOf('/') + 1)
    $DestFile = $DownloadDir + '\' + $SetupName

    Start-BitsTransfer -Source $SetupUrl -Destination $DestFile -Description "Downloading $SetupName ..."

    if (Test-Path $DestFile) {
        $DestFile
    } else {
        Write-Error 'Es ist ein Fehler beim Herunterladen der Datei' + $SetupUrl + 'aufgetreten.'
    }
    
}


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

    if ($Beta) {
        $SetupName = "${SetupBaseName}Beta.exe"
    } elseif ($Test) {
        $SetupName = "${SetupBaseName}Test.exe"
    } else {
        $SetupName = "${SetupBaseName}.exe"
    }

    $SourceFile = "$BaseUrl/$SetupName"
    $DestFile = $DownloadDir + '\' + $SetupName

    Start-BitsTransfer -Source $SourceFile -Destination $DestFile -Description "Downloading $SourceFile ..."

    if (Test-Path $DestFile) {
        $DestFile
    } else {
        Write-Error 'Es ist ein Fehler beim Herunterladen der Datei' + $SourceFile + 'aufgetreten.'
    }
    
}



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]$DestFile
    )

    # Verify that setup exist
    if (!(Test-Path -Path $DestFile)) {
        Write-Warning 'Die Setup-Datei' $DestFile 'wurde nicht gefunden.'
        Break
    }

    $Command = 'msiexec'
    $CommandArgs = @(
        "/package",
        "`"$DestFile`"",
        "SERVICENAME=MySql",
        "INSTALLDIR=`"$env:ProgramFiles\MariaDB`"",
        "ALLOWREMOTEROOTACCESS=True",
        "PASSWORD=root",
        "/qn"
    )

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

    Start-Process -FilePath $Command $CommandArgs -Wait
}




function Install-GreyhoundServer {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$true,
        ValueFromPipeline)]
        [String]$DestFile,
        [String]$ContractNo,
        [String]$SerialNo
    )

    # Verify that both setups exist
    if (!(Test-Path -Path $DestFile)) {
        Write-Warning 'Die Setup-Datei' $DestFile 'wurde nicht gefunden.'
        Break
    }

    $Command = $DestFile
    $CommandArgs = @(
        "-silent",
        "-contract $ContractNo",
        "-serial $SerialNo",
        "-kind server",
        "-nodesktop",
        "-nostartmenu",
        "-noquicklaunch",
        "-nodefaultmail",
        "-noprinterdriver",
        "-databaseuser", "root",
        "-databasepass", "root",
        "-databasetemplate", "large",
        "-adminpassword", "admin"
    )

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

    Start-Process -FilePath $Command $CommandArgs -Wait
}



function Test-TestFunction {
    Write-Host 'Das ist eine Testfunktion.'
}