MSFT_BizTalkServer.psm1

Import-Module PSDesiredStateConfiguration

enum Ensure 
{ 
    Absent 
    Present 
}

enum HostType 
{ 
    InProcess
    Isolated
}

[DscResource()]
class BizTalkServerHost
{
    [DscProperty(Key)]
    [string]$Name

    [DscProperty(Mandatory)]
    [bool] $Trusted

    [DscProperty(Mandatory)]
    [bool] $Tracking

    [DscProperty(Mandatory)]
    [HostType] $Type

    [DscProperty(Mandatory)]
    [bool] $Is32Bit

    [DscProperty(Mandatory)]
    [bool] $Default

    [DscProperty(Mandatory)]
    [string] $WindowsGroup

    [DscProperty(Mandatory)]
    [Ensure] $Ensure

    [string] $namespace = 'ROOT\MicrosoftBizTalkServer'

    [void] Set()
    {
        if($this.Ensure -eq [Ensure]::Present)
        {
            $properties = @{
                Name = $this.Name;
                AuthTrusted = $this.Trusted;
                HostTracking = $this.Tracking;
                HostType = &{if($this.Type -eq [HostType]::Inprocess) {1} else {2}};
                IsDefault = $this.Default;
                IsHost32BitOnly = $this.Is32Bit;
                NTGroupName = $this.WindowsGroup;
                MgmtDbServerOverride = '';
                MgmtDbNameOverride = ''
            }

            $instanceClass = Get-CimClass -ClassName MSBTS_HostSetting -Namespace $this.namespace

            $instance = New-CimInstance -CimClass $instanceClass  -Property $properties

            Set-CimInstance -InputObject $instance
        }
        else
        {
            $query = "SELECT * FROM MSBTS_HostSetting WHERE Name='$($this.Name)'"

            $instance = Get-CimInstance -Query $query -Namespace $this.namespace

            if($null -ne $instance)
            {
                Remove-CimInstance -InputObject $instance
            }
        }
    }

    [bool] Test()
    {
        $query = "SELECT * FROM MSBTS_HostSetting WHERE Name='$($this.Name)'"

        Write-Verbose "Ensure : $($this.Ensure)"
        Write-Verbose "Namespace : $($this.namespace)"
        Write-Verbose "Query: $query"

        $instance = Get-CimInstance -Query $query -Namespace $this.namespace

        if($this.Ensure -eq [Ensure]::Present)
        {
            $result = ($null -ne $instance)
        }
        else
        {
            $result = ($null -eq $instance)
        }

        Write-Verbose "Test: $result"
        
        return $result
    }

    [BizTalkServerHost] Get()
    {
        $result = $this.Test()

        if($result)
        {
            return $this
        }
        else
        {
            return $null
        }
    }
}

[DscResource()]
class BizTalkServerHostInstance
{
    [DscProperty(Key)]
    [string]$Host

    [DscProperty(Mandatory)]
    [pscredential] $Credentials

    [DscProperty(Mandatory)]
    [Ensure] $Ensure

    [string] $namespace = 'ROOT\MicrosoftBizTalkServer'

    [void] Set()
    {
        if($this.Ensure -eq [Ensure]::Present){
            Write-Verbose "Create MSBTS_ServerHost $($this.Host)"

            $instanceClass = Get-CimClass -Namespace $this.namespace –ClassName MSBTS_ServerHost

            $properties = @{
                ServerName = $($env:COMPUTERNAME);
                HostName = $($this.Host);
                MgmtDbNameOverride='';
                MgmtDbServerOverride='';
            }

            $instance = New-CimInstance -CimClass $instanceClass -Property $properties -ClientOnly

            $arguments = @{}

            Invoke-CimMethod -InputObject $instance -MethodName Map -Arguments $arguments

            Write-Verbose "Create MSBTS_HostInstance $($this.Host)"

            $instanceClass = Get-CimClass -Namespace $this.namespace –ClassName MSBTS_HostInstance

            $name = "Microsoft BizTalk Server $($this.Host) $($env:COMPUTERNAME)"

            $properties = @{
                Name =$name;
                MgmtDbNameOverride='';
                MgmtDbServerOverride='';
            }

            $instance = New-CimInstance -CimClass $instanceClass -Property $properties -ClientOnly

            $user = $this.Credentials.UserName
            $password = $this.Credentials.GetNetworkCredential().Password

            $arguments = @{
                GrantLogOnAsService = $true;
                Logon = $user;
                Password = $password;
            }

            Invoke-CimMethod -InputObject $instance -MethodName Install -Arguments $arguments
        }
        else{
            $query = "SELECT * FROM MSBTS_HostInstance WHERE HostName='$($this.Host)'"

            $instance = Get-CimInstance -Query $query -Namespace $this.namespace

            Write-Verbose "Find MSBTS_HostInstance $($this.Host)"

            $arguments = @{}

            if($null -ne $instance){
                if($instance.ServiceState =eq 4){
                    Write-Verbose "Stop MSBTS_HostInstance $($this.Host)"
                    Invoke-CimMethod -InputObject $instance -MethodName Stop -Arguments $arguments
                }

                Write-Verbose "UnInstall MSBTS_HostInstance $($this.Host)"

                Invoke-CimMethod -InputObject $instance -MethodName UnInstall -Arguments $arguments
            }

            Write-Verbose "UnMap MSBTS_ServerHost $($this.Host)"

            $instanceClass = Get-CimClass -Namespace $this.namespace –ClassName MSBTS_ServerHost

            $properties = @{
                ServerName = $($env:COMPUTERNAME);
                HostName = $($this.Host);
                MgmtDbNameOverride='';
                MgmtDbServerOverride='';
            }

            $instance = New-CimInstance -CimClass $instanceClass -Property $properties -ClientOnly

            Invoke-CimMethod -InputObject $instance -MethodName ForceUnmap -Arguments $arguments
        }
    }

    [bool] Test()
    {
        $query = "SELECT * FROM MSBTS_HostInstance WHERE HostName='$($this.Host)'"

        Write-Verbose "Ensure : $($this.Ensure)"
        Write-Verbose "Namespace : $($this.namespace)"
        Write-Verbose "Query: $query"

        $instance = Get-CimInstance -Query $query -Namespace $this.namespace

        if($this.Ensure -eq [Ensure]::Present){
            $result = ($null -ne $instance)
        }
        else{
            $result = ($null -eq $instance)
        }

        Write-Verbose "Test: $result"
        
        return $result
    }

    [BizTalkServerHostInstance] Get()
    {
        $result = $this.Test()

        if($result){
            return $this
        }
        else{
            return $null
        }
    }
}