internal/Invoke-ManagedComputerCommand.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
Function Invoke-ManagedComputerCommand
{
<#
.SYNOPSIS
Internal command
 
#>
    
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [Alias("ComputerName")]
        [object]$Server,
        [System.Management.Automation.PSCredential]$Credential,
        [Parameter(Mandatory = $true)]
        [scriptblock]$ScriptBlock,
        [string[]]$ArgumentList
    )
    
    if ($Server.GetType() -eq [Microsoft.SqlServer.Management.Smo.Server])
    {
        $server = $server.ComputerNamePhysicalNetBIOS
    }
    
    # Remove instance name if it as passed
    $server = ($Server.Split("\"))[0]
    
    if ($Server -eq $env:COMPUTERNAME -or $Server -eq 'localhost' -or $Server -eq '.')
    {
        $Server = 'localhost'
        if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
        {
            throw "This command must be run with elevated privileges for the local host."
        }
    }
    
    $ipaddr = (Test-Connection $server -Count 1 -ErrorAction Stop).Ipv4Address
    $ArgumentList += $ipaddr
        
    [scriptblock]$setupScriptBlock = {
        $ipaddr = $args[$args.GetUpperBound(0)]
        
        # Just in case we go remote, ensure the assembly is loaded
        [void][System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SqlWmiManagement')
        
        $wmi = New-Object Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer $ipaddr
        $null = $wmi.Initialize()
    }
    
    $prescriptblock = $setupScriptBlock.ToString()
    $postscriptblock = $ScriptBlock.ToString()
    
    $scriptblock = [ScriptBlock]::Create("$prescriptblock $postscriptblock")
        
    try
    {
        if ($credential.username -ne $null)
        {
            $result = Invoke-Command -ScriptBlock $ScriptBlock -ArgumentList $ArgumentList -Credential $Credential
        }
        else
        {
            $result = Invoke-Command -ScriptBlock $ScriptBlock -ArgumentList $ArgumentList
        }
        
        Write-Verbose "Local connection for $server succeeded"
    }
    catch
    {
        try
        {
            Write-Verbose "Local connection attempt to $Server failed. Connecting remotely."
            
            # For surely resolve stuff
            $hostname = [System.Net.Dns]::gethostentry($ipaddr)
            $hostname = $hostname.HostName
            
            if ($credential.username -ne $null)
            {
                $result = Invoke-Command -ScriptBlock $ScriptBlock -ArgumentList $ArgumentList -Credential $Credential -ComputerName $hostname
            }
            else
            {
                $result = Invoke-Command -ScriptBlock $ScriptBlock -ArgumentList $ArgumentList -ComputerName $hostname
            }
        }
        catch
        {
            Write-Exception $_
            throw $_
        }
    }
    
    $result | Select-Object * -ExcludeProperty PSComputerName, RunSpaceID, PSShowComputerName
}