DSCResources/MSFT_xTFSConfig/MSFT_xTFSConfig.schema.psm1

Configuration MSFT_xTFSConfig
{
    param
    (
        [String] $Ensure = "Present",

        [Parameter(Mandatory)]
        [PSCredential] $Credential,

        [Parameter(Mandatory)]
        [String] $Version,

        [String] $Arguments,

        [String] $MachineName
    )

    Import-DscResource -Module xPSDesiredStateConfiguration -Name MSFT_xPackageResource

    $tfsConfigExePath = Get-TFSConfigExePath -Version $Version -MachineName $MachineName
    Write-Verbose ("TFS config executable (`$Version={0}): $tfsConfigExePath" -f $Version)

    $regPath = Get-TFSConfigRegistryPath -Version $Version -MachineName $MachineName
    
    $regName = $regPath.Name
    $tfsConfigRegName = $regName.subString($regName.indexOf('\')+1)
    Write-Verbose ("TFS config registry path for (`$Version={0}): $tfsConfigRegName" -f $Version)

    xPackage ConfigureTFS
    {
        Ensure = $Ensure
        Name = $TFS_CONFIGURE
        Path = $tfsConfigExePath
        ProductId = ""
        RunAsCredential = $Credential
        Arguments = $Arguments
        ReturnCode = @(0, 3010)
        InstalledCheckRegKey = $tfsConfigRegName
        InstalledCheckRegValueName = $IS_CONFIGURED
        InstalledCheckRegValueData = "1"
    }
}

$INSTALL_CHECK_REG_32_KEY = "SOFTWARE\Microsoft\TeamFoundationServer"
$INSTALL_CHECK_REG_64_KEY = "SOFTWARE\Wow6432Node\Microsoft\TeamFoundationServer"
$INSTALLPATH = "InstallPath"
$TFS_CONFIG_EXE = "TFSConfig.exe"
$INSTALLED_COMPONENTS = "InstalledComponents"
$APPLICATION_TIER = "ApplicationTier"
$IS_CONFIGURED = "IsConfigured"
$TFS_CONFIGURE = "TFS Configure"
$TOOLS = "Tools"

function Test-IsTFSInstalled([string] $MachineName)
{
    $isInstalled = $true
    $baseKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $MachineName)
    $subkey = $basekey.OpenSubKey($INSTALL_CHECK_REG_32_KEY)

    if(-not $subKey)
    {
        $subKey = $baseKey.OpenSubKey($INSTALL_CHECK_REG_64_KEY)
        if(-not $subKey)
        {
            $isInstalled = $false
        }
    }
    
    #return the TFS install status along with the TFS base registry key
    return @{
                Installed = $isInstalled
                BaseRegPath = $subkey
            }
}

function Get-TFSRegistryPath([string] $Version, [Microsoft.Win32.RegistryKey] $BaseTFSRegKey)
{    
    if ([string]::IsNullOrWhiteSpace($Version))
    {
        $subKeys = $BaseTFSRegKey.GetSubKeyNames()
        $Version = $subkeys | Sort-Object -Descending | Select-Object -First 1
        if ([string]::IsNullOrWhiteSpace($Version))
        {
            throw("No TFS version found under registry path {0}" -f $BaseTFSRegKey)
        }
    }
    
    return $BaseTFSRegKey.OpenSubKey("{0}\$INSTALLED_COMPONENTS" -f $Version)    
}

function Get-TFSConfigExePath([string] $Version, [string] $MachineName)
{
    $TFSDetails= Test-IsTFSInstalled -Version $Version -MachineName $MachineName
    if(-not $TFSDetails.Installed)
    {
        throw("TFS is not installed")
    }
    
    $installRegPath = Get-TFSRegistryPath -Version $Version -BaseTFSRegKey $TFSDetails.BaseRegPath
    if(-not $installRegPath)
    {
        throw("Unable to get TFS's installed components registry path")
    }
   
    $toolsRegPath = $installRegPath.OpenSubKey($TOOLS)
    if(-not $toolsRegPath)
    {        
        throw("Unable to open registry key {0}\{1}" -f $installRegPath, $TOOLS)
    }

    $installedPath = $toolsRegPath.GetValue($INSTALLPATH)
    if([string]::IsNullOrWhiteSpace($installedPath))
    {
        throw("{0} property is not found for registry path {1}" -f $INSTALLPATH, $toolsRegPath)
    }
    
    $configExePath = Join-Path -Path $installedPath -ChildPath $TFS_CONFIG_EXE
    return $configExePath
}

function Get-TFSConfigRegistryPath([string] $Version, [string] $MachineName)
{
    $TFSDetails= Test-IsTFSInstalled -Version $Version -MachineName $MachineName
    if(-not $TFSDetails.Installed)
    {
        throw("TFS is not installed")
    }
    
    $installRegPath = Get-TFSRegistryPath -Version $Version -BaseTFSRegKey $TFSDetails.BaseRegPath
    if(-not $installRegPath)
    {
        throw("Unable to get TFS's installed components registry path")
    }
   
    $atRegKey = $installRegPath.OpenSubKey($APPLICATION_TIER)
    if(-not $atRegKey)
    {        
        throw("Unable to open registry key $installRegPath\{0}" -f $atRegKey)
    }

    return $atRegKey
}