Modules/DSCR_MIMSettings.Util/Invoke-SPDscCommand.psm1

function Invoke-SPDscCommand
{
    [CmdletBinding()]
    param
    (
        [Parameter()]
        [System.Management.Automation.PSCredential]
        $Credential,

        [Parameter()]
        [Object[]]
        $Arguments,

        [Parameter(Mandatory = $true)]
        [ScriptBlock]
        $ScriptBlock
    )

    $VerbosePreference = 'Continue'

    $baseScript = @"
        if (`$null -eq (Get-PSSnapin -Name Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue))
        {
            Add-PSSnapin Microsoft.SharePoint.PowerShell
        }
 
        `$SaveVerbosePreference = `$VerbosePreference
        `$VerbosePreference = 'SilentlyContinue'
        `$VerbosePreference = `$SaveVerbosePreference
 
"@


    $invokeArgs = @{
        ScriptBlock = [ScriptBlock]::Create($baseScript + $ScriptBlock.ToString())
    }
    if ($null -ne $Arguments)
    {
        $invokeArgs.Add("ArgumentList", $Arguments)
    }

    if ($null -eq $Credential)
    {
        if ($Env:USERNAME.Contains("$"))
        {
            throw [Exception] ("You need to specify a value for either InstallAccount " + `
                    "or PsDscRunAsCredential.")
            return
        }
        Write-Verbose -Message "Executing as the local run as user $($Env:USERDOMAIN)\$($Env:USERNAME)"

        try
        {
            return Invoke-Command @invokeArgs -Verbose
        }
        catch
        {
            if ($_.Exception.Message.Contains("An update conflict has occurred, and you must re-try this action"))
            {
                Write-Verbose -Message ("Detected an update conflict, restarting server to " + `
                        "allow DSC to resume and retry")
                $global:DSCMachineStatus = 1
            }
            else
            {
                throw $_
            }
        }
    }
    else
    {
        if ($Credential.UserName.Split("\")[1] -eq $Env:USERNAME)
        {
            if (-not $Env:USERNAME.Contains("$"))
            {
                throw [Exception] ("Unable to use both InstallAccount and " + `
                        "PsDscRunAsCredential in a single resource. Remove one " + `
                        "and try again.")
                return
            }
        }
        Write-Verbose -Message ("Executing using a provided credential and local PSSession " + `
                "as user $($Credential.UserName)")

        # Running garbage collection to resolve issues related to Azure DSC extention use
        [GC]::Collect()

        $session = New-PSSession -ComputerName $env:COMPUTERNAME `
            -Credential $Credential `
            -Authentication CredSSP `
            -Name "Microsoft.SharePoint.DSC" `
            -SessionOption (New-PSSessionOption -OperationTimeout 0 `
                -IdleTimeout 60000) `
            -ErrorAction Continue

        if ($session)
        {
            $invokeArgs.Add("Session", $session)
        }

        try
        {
            return Invoke-Command @invokeArgs -Verbose
        }
        catch
        {
            if ($_.Exception.Message.Contains("An update conflict has occurred, and you must re-try this action"))
            {
                Write-Verbose -Message ("Detected an update conflict, restarting server to " + `
                        "allow DSC to resume and retry")
                $global:DSCMachineStatus = 1
            }
            else
            {
                throw $_
            }
        }
        finally
        {
            if ($session)
            {
                Remove-PSSession -Session $session
            }
        }
    }
}
Export-ModuleMember -Function *