Public/New-ISInstance.ps1

function ModuleRoot { $MyInvocation.ScriptName | Split-Path -Parent}
$PrivPath = $(Join-Path $(ModuleRoot | Split-Path -Parent) "\Private")
. "$PrivPath\NewInstanceHelperFunctions.ps1"
. "$PrivPath\New-SymLink.ps1"

<#
.SYNOPSIS
    Creates a new instance of an IntelliSearch component
.DESCRIPTION
    The New-ISComponentInstance cmdlet will create a new, blank component from an installed component package, complete with a Windows service.
.EXAMPLE
    Install-ISComponentFromNuGet -Name FileshareConnector | New-ISComponentInstance -Name FileShare
.EXAMPLE
    Get-ISComponent -Name Crawler* | New-ISComponentInstance -Name FileCrawlerManager
.INPUTS
    Component, System.String
.OUTPUTS
    Instance
#>

function New-ISInstance
{
    [CmdletBinding(ConfirmImpact = 'Low')]
    [OutputType()]
    param(
        [Parameter(
            Mandatory = $true,
            Position = 0,
            ValueFromPipelineByPropertyName = $true
        )]
        [ValidateNotNull()]
        [ValidateNotNullOrEmpty()]
        [Alias("ComponentName")]
        [String] $Name,

        [Parameter(
            Mandatory = $true,
            Position = 1,
            ValueFromPipelineByPropertyName = $true
        )]
        [ValidateScript( { Test-Path $_ -PathType Container})]
        [Alias()]
        [String] $ComponentDirectory,

        [Parameter(
            Mandatory = $false,
            ValueFromPipelineByPropertyName = $true
        )]
        [Alias()]
        [ValidateScript( { Test-Path $_ -IsValid})]
        [String] $Path = $IS_Settings.InstanceStore
    )

    begin
    {

    }

    process
    {
        Write-Verbose ("Making new instance {0}" -f $Name)
        if (-not (Test-Path $Path -IsValid))
        {
            Write-Error "Instance path is not valid. Got: $($Path)" -ErrorAction:Stop
        }
        
        $SetupConf = Join-Path $ComponentDirectory "\etc\ISPSInstance.config"
        if (-not (Test-Path $SetupConf))
        {
            Write-Error "Found no valid ISPSInstance.config" -ErrorAction:Stop
        }
        
        Write-Verbose ("Processing ISPSInstance.config for {0}" -f $Name)
        $Xml = New-Object System.Xml.XmlDocument
        $Xml.Load($SetupConf)
        
        $InstanceDirectory = (Join-Path $Path $Name)

        if (Test-Path $InstanceDirectory -PathType Container)
        {
            Write-Error "Instance names must be unique" -ErrorAction:Stop
        }

        $InstallBinPath = Get-ChildItem -Path $ComponentDirectory -Directory | Where-Object { $_.Name -like "bin"}
        $InstallCfgPath = Get-ChildItem -Path $ComponentDirectory -Directory | Where-Object { $_.Name -like "cfg"}

        $InstanceDirectory = New-Item -Path $InstanceDirectory -ItemType Container

        foreach ($Node in $Xml.SelectNodes("//IntelliSearchComponent/*"))
        {   
            switch ($Node.Name)
            {
                "Service"
                {
                    Write-Verbose "Creating new service"
                    $InstanceBinPath = Join-Path $InstanceDirectory "/bin"
                    New-SymLink -Path $InstallBinPath.FullName -SymName $InstanceBinPath -Directory | Out-Null

                    $CopySplat = @{
                        Path        = $InstallCfgPath.FullName
                        Destination = $InstanceDirectory.FullName
                        PassThru    = $true
                        Force       = $true
                        Recurse     = $true
                    }
                    Copy-Item @CopySplat | Out-Null

                    $InstanceExePath = Join-Path $InstanceDirectory $Node.Executable
                    $InstanceCfgFile = Join-Path $InstanceDirectory $Node.ConfigurationFile
                    CreateService $Name $InstanceExePath $InstanceCfgFile $Node.StartupArgument
                }

                "Shortcut"
                {
                    Write-Verbose "Creating new shortcut"
                    $ShortcutName = $Node.ShortcutName
                    if ($ShortcutName -notmatch '.+\.(?:lnk|url)$')
                    {
                        $ShortcutName = $ShortcutName + ".lnk"
                    }

                    if ($ShortcutName -match '.+\.lnk$')
                    {
                        $ShortcutTarget = Join-Path $ComponentDirectory $Node.Target
                        if ($Node.StartupArgument)
                        {
                            $ShortcutArguments = $Node.StartupArgument -f (Join-Path $InstanceDirectory $Node.ConfigurationFile)
                        }
                    }
                    elseif ($ShortcutName -match '.+\.url$')
                    {
                        $ShortcutTarget = $Node.Target
                        $ShortcutArguments = $null
                    }
                    
                    $ShortcutDestination = Join-Path $InstanceDirectory $ShortcutName
                    CreateShortcut $ShortcutTarget $ShortcutDestination $ShortcutArguments
                }

                "WebApplication"
                {
                    Write-Verbose "Creating new WebApplication"
                    CreateWebApplication $Node $Name $ComponentDirectory $InstanceDirectory
                }

                Default
                {
                    Write-Verbose "Node did not return a known type. Got $($Node.Name)"
                }
            }
        }
    }

    end
    {

    }

}