DSCResources/MSFT_xSqlServerMoveDatabaseFiles/MSFT_xSqlServerMoveDatabaseFiles.psm1

function Get-TargetResource
{
    [CmdletBinding()]
    [OutputType([System.Collections.Hashtable])]
    param
    (
        [parameter(Mandatory = $true)]
        [System.String]
        $SQLServer,

        [parameter(Mandatory = $true)]
        [System.String]
        $SQLInstanceName,

        [parameter(Mandatory = $true)]
        [System.String]
        $Database
    )

    #Write-Verbose "Use this cmdlet to deliver information about command processing."

    #Write-Debug "Use this cmdlet to write debug information while troubleshooting."

    if ($SQLInstanceName -eq 'MSSQLSERVER')
    {
        $serverInstance = $SQLServer;
    }
    else {    
        $serverInstance = Join-Path -Path $SQLServer -ChildPath $SQLInstanceName;
    }

    $returnValue = @()
    
    foreach ($db in ($Database -split ','))
    {

        # get the current paths
        $files = Invoke-Sqlcmd -ServerInstance $serverInstance -Database 'master' -Query "SELECT db_name(database_id) [dbname], name, physical_name AS CurrentLocation, state_desc, type FROM sys.master_files WHERE database_id = DB_ID(N'$db');"
        
        foreach ($file in $files)
        {
            if ($file.Type -eq 0)
            {
                $currentDataPath = Split-Path -Path $file.CurrentLocation -Parent
            }
            else {
                $currentLogPath = Split-Path -Path $file.CurrentLocation -Parent
            }
        }

        $returnValue += [PSCustomObject]@{
            SQLServer = [System.String]$SQLServer
            SQLInstanceName = [System.String]$SQLInstanceName
            Database = [System.String]$db
            DataPath = [System.String]$currentDataPath
            LogPath = [System.String]$currentLogPath
        }
    }

    $returnValue

}


function Set-TargetResource
{
    [CmdletBinding()]
    param
    (
        [parameter(Mandatory = $true)]
        [System.String]
        $SQLServer,

        [parameter(Mandatory = $true)]
        [System.String]
        $SQLInstanceName,

        [ValidateSet("Present","Absent")]
        [System.String]
        $Ensure,

        [parameter(Mandatory = $true)]
        [System.String]
        $Database,

        [System.String]
        $DataPath,

        [System.String]
        $LogPath
    )

    #Write-Verbose "Use this cmdlet to deliver information about command processing."

    #Write-Debug "Use this cmdlet to write debug information while troubleshooting."

    #Include this line if the resource requires a system reboot.
    #$global:DSCMachineStatus = 1

    if ($SQLInstanceName -eq 'MSSQLSERVER')
    {
        $serverInstance = $SQLServer;
    }
    else {    
        $serverInstance = Join-Path -Path $SQLServer -ChildPath $SQLInstanceName;
    }

    $filesToProcess = @()

    foreach ($db in ($Database -split ','))
    {
        Write-Verbose "Getting files for Database: $db";

        $tsql = "SELECT db_name(database_id) [dbname], name, physical_name AS CurrentLocation, state_desc, type FROM sys.master_files WHERE database_id = DB_ID(N'$db');";
        $files = Invoke-Sqlcmd -ServerInstance $serverInstance -Database 'master' -Query $tsql;
        
        foreach ($file in $files)
        {

            $fileName = Split-Path -Path $file.CurrentLocation -Leaf;

            if ($file.Type -eq 0)
            {
                $newPath = Join-Path -Path $DataPath -ChildPath $fileName;
            }
            else {
                $newPath = Join-Path -Path $LogPath -ChildPath $fileName;
            }
            $tsql = "ALTER DATABASE [$db] MODIFY FILE ( NAME = '$($file.Name)' , FILENAME = '$($newPath)' )"
            Invoke-Sqlcmd -ServerInstance $serverInstance -Database 'master' -Query $tsql;

            $filesToProcess += [PSCustomObject]@{
                FileName = $fileName;
                CurrentPath = $file.CurrentLocation;
                NewPath = $newPath;
            }
        }
    }

    # stop the service
    if ((Get-Service -Name $SqlInstanceName).Status -ne 'Stopped')
    {
        Stop-Service -Name $SqlInstanceName -Force
        (Get-Service -Name $SqlInstanceName).WaitForStatus('Stopped')
    }

    # move the files
    foreach ($file in $filesToProcess)
    {
        # make sure this file actually needs to be moved
        if ($file.CurrentPath -ne $file.NewPath)
        {
            Write-Verbose "Moving '$($file.CurrentPath)' to '$($file.NewPath)'";
            Move-Item -Path $file.CurrentPath -Destination $file.NewPath -Force;
        }
        else {
            Write-Verbose "Skipped moving '$($file.CurrentPath)' as desired path already used";
        }
    }

    # start the service
    if ((Get-Service -Name $SqlInstanceName).Status -ne 'Running')
    {
        Start-Service -Name $SqlInstanceName
        (Get-Service -Name $SqlInstanceName).WaitForStatus('Running')
    }


}


function Test-TargetResource
{
    [CmdletBinding()]
    [OutputType([System.Boolean])]
    param
    (
        [parameter(Mandatory = $true)]
        [System.String]
        $SQLServer,

        [parameter(Mandatory = $true)]
        [System.String]
        $SQLInstanceName,

        [ValidateSet("Present","Absent")]
        [System.String]
        $Ensure,

        [parameter(Mandatory = $true)]
        [System.String]
        $Database,

        [System.String]
        $DataPath,

        [System.String]
        $LogPath
    )

    #Write-Verbose "Use this cmdlet to deliver information about command processing."

    #Write-Debug "Use this cmdlet to write debug information while troubleshooting."
    if ($SQLInstanceName -eq 'MSSQLSERVER')
    {
        $serverInstance = $SQLServer;
    }
    else {    
        $serverInstance = Join-Path -Path $SQLServer -ChildPath $SQLInstanceName;
    }

    # return value
    [System.Boolean]$success = $true;

    # process each of the databases
    foreach ($db in ($Database -split ','))
    {
        $files = Invoke-Sqlcmd -ServerInstance $serverInstance -Database 'master' -Query "SELECT db_name(database_id) [dbname], name, physical_name AS CurrentLocation, state_desc, type FROM sys.master_files WHERE database_id = DB_ID(N'$db');"
        
        foreach ($file in $files)
        {
            if ($file.Type -eq 0)
            {
                $currentDataPath = Split-Path -Path $file.CurrentLocation -Parent
                if ($currentDataPath -ne $DataPath) {$success = $false}
            }
            else {
                $currentLogPath = Split-Path -Path $file.CurrentLocation -Parent
                if ($currentLogPath -ne $LogPath) {$success = $false}
            }
        }
    }

    return $success
    
    <#
    $result = [System.Boolean]
     
    $result
    #>

}


Export-ModuleMember -Function *-TargetResource