วิธีที่มีประสิทธิภาพมากที่สุดในการค้นหาอินสแตนซ์ที่ทำงานอยู่ทั้งหมดของ SQL Server โดยใช้ PowerShell คืออะไร


13

ฉันได้รับมอบหมายให้ค้นหาอินสแตนซ์ทั้งหมดของ SQL Server ที่ทำงานอยู่ภายในโดเมนของเรา ในหลายกรณีมีหลายอินสแตนซ์ต่อเซิร์ฟเวอร์ ฉันเห็นวิธี PowerShell สองวิธีที่แตกต่างกันในการค้นหาอินสแตนซ์เหล่านี้ แต่ดูเหมือนจะไม่พบอินสแตนซ์ทั้งหมด

1) ใช้ WMI

        $srvr = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer $computerName
    $instances = $srvr | ForEach-Object {$_.ServerInstances} | Select @{Name="fullName";Expression={$computerName +"\"+ $_.Name}}   
    return $instances

2) ใช้รีจิสตรีระยะไกล (เช่นเดียวกับ Get-SQLInstance 1 )

ปัญหาที่ใหญ่ที่สุดที่ฉันพบคือเซิร์ฟเวอร์ทั้งหมดที่ฉันรู้จักไม่ทำงานกับผู้ให้บริการ SQL Server WMI และไม่อนุญาตให้ใช้รีจิสตรีระยะไกล มีวิธีที่สามหรือไม่? ฉันสามารถใช้ Remote Desktop เพื่อเข้าถึงเซิร์ฟเวอร์ทั้งหมด แต่ฉันกำลังดูเครื่องจักรประมาณ 30 เครื่องและต้องการหลีกเลี่ยงขั้นตอนแบบแมนนวลหากเป็นไปได้ สิ่งนี้ต้องการทำงานสำหรับ SQL Server 2008 และสูงกว่าและในขณะที่มันน่าจะรู้เกี่ยวกับบริการอื่น ๆ ของ SQL Server (SSIS / SSAS / SSRS) จุดสนใจหลักของฉันคือ SQL Server เอง


คำตอบ:


12

หากคุณต้องการสิ่งที่จะเป็นประโยชน์สำหรับอนาคตฉันอาจจะหลีกเลี่ยงการพยายามค้นหารีจิสทรี ลมพิษสำหรับ SQL Server มีการเปลี่ยนแปลงเล็กน้อยในช่วงหลายปีที่ผ่านมาและอาจเป็นปัญหาในการติดตาม

วิธีการที่SqlDataSourceEnumeratorไม่สม่ำเสมอในบางครั้งและถึงแม้ว่าฉันจะใช้มันไม่ใช่หลักฐานที่ชัดเจนว่ามีอินสแตนซ์อยู่ในเครือข่าย ฉันเชื่อว่ามันขึ้นอยู่กับ SQL Browser Service ด้วยซึ่งส่วนใหญ่ฉันพบว่าปิดการใช้งาน

win32_Serviceฉันจะใช้ชั้น WMI ฉันใช้สิ่งนี้เพราะให้ข้อมูลเพิ่มเติมเกี่ยวกับบริการมากกว่าที่Get-Servicecmdlet ทำ

ฉันเขียนทุกอย่างเป็นฟังก์ชั่นโดยทั่วไปเพราะคุณสามารถใช้สิ่งนี้เพื่อตรวจสอบรายวันหรือตรวจสอบบริการเพื่อแก้ไขปัญหา

function Get-ServiceStatus ([string[]]$server)
{
 foreach ($s in $server)
 {
   if(Test-Connection $s -Count 2 -Quiet)
   {
    Get-WmiObject win32_Service -Computer $s |
     where {$_.DisplayName -match "SQL Server"} | 
     select SystemName, DisplayName, Name, State, Status, StartMode, StartName
   }
 }
}

นี่เป็นอะไรที่มากกว่าปกติฉันใช้ แต่ในกรณีที่มีคนอื่นเจอและต้องการใช้มัน Test-Connectionเท่ากับping myserverใน DOS ให้และ-Quietธงเพียงแค่ได้มันกลับมาหรือtrue falseสิ่งนี้จะมีค่าเริ่มต้นเป็น 4 pings ดังนั้นการตั้งค่า-Count 2ทำได้เพียงสองครั้งแทน

ตัวแปร[string[]]$serverเป็นวิธีที่ใช้ในการระบุว่า$serverจะยอมรับอาร์เรย์ของชื่อเซิร์ฟเวอร์ ดังนั้นตัวอย่างการเรียกใช้ฟังก์ชันนี้อาจมีลักษณะดังนี้:

Get-ServiceStatus -server (Get-Content C:\temp\MyServerList.txt)

หรือ

$servers = 'MyServer1','MyServer2','MyServer3'
Get-ServiceStatus -server $servers

แก้ไข

ความคิดเห็นที่ระบุไว้ข้างต้นจะขึ้นอยู่กับรายการของเซิร์ฟเวอร์ที่ให้ไว้ ในกรณีที่ฉันไม่ได้ระบุว่าคุณมีตัวเลือกอื่น ๆ

  • ถ้าฉันอยู่ในสภาพแวดล้อมของ Active Directory ฉันสามารถใช้โมดูลActiveDirectoryใน PowerShell เพื่อดึงรายการเซิร์ฟเวอร์ทั้งหมดในโดเมนด้วยGet-ADComputercmdlet คำเตือนแม้ว่าให้แน่ใจว่าคุณใช้ดี-Filterในโดเมนขนาดใหญ่

  • ฉันเพิ่งทำการสแกน IP (ด้วยการอนุมัติ) ของเครือข่ายที่ให้ที่อยู่ IP ที่พบพอร์ต 1433 เปิดอยู่ ฉันจะใช้รายการ IP นั้นและใช้Get-ADComputerเพื่อค้นหาชื่อคอมพิวเตอร์โดเมนจากนั้นส่งผ่านไปยังฟังก์ชั่นด้านบน

ตัวอย่าง:

Import-Module ActiveDirectory
$sList = $ipList | Select -ExpandProperty IP
$results = foreach ($i in $sList) { 
 Get-ADComputer -Filter 'IPv4Address -eq $i' -Properties * | Select Name}
Get-ServiceStatus -server $results

แก้ไข

การแก้ไขที่แนะนำเพื่อใช้Write-Verboseและเพิ่มในลอง / จับบล็อกในขณะที่อาจมีประโยชน์และในกรณีส่วนใหญ่การฝึกรหัสฉันจะปล่อยให้ขึ้นอยู่กับคนที่ต้องการใช้ฟังก์ชั่นนี้เพื่อเพิ่มรหัสหรือฟังก์ชั่นเพิ่มเติม เพียงแค่พยายามให้ตัวอย่างพื้นฐานเพื่อดำเนินการต่อ ฉันเพิ่มSystemNameคุณสมบัติไปยังเอาต์พุตเพื่อรวมชื่อเซิร์ฟเวอร์ที่ส่งคืนข้อมูลจริงทำสิ่งนี้ในฟังก์ชั่นอื่น ๆ โดยทั่วไปไม่ใช้สิ่งนี้กับเซิร์ฟเวอร์มากกว่าหนึ่งเครื่องในแต่ละครั้งดังนั้นมันจึงลื่นใจ


สิ่งนี้จะช่วยให้คุณได้รับรายชื่อเซิร์ฟเวอร์ที่จะเริ่มต้นด้วย ไม่สามารถคาดเดาได้เสมอไป
Thomas Stringer

เพียงเพื่อความชัดเจนการ จำกัด การสแกนไปยังพอร์ต 1433 จะทำให้เซิร์ฟเวอร์ใด ๆ ที่มีอินสแตนซ์ที่ตั้งชื่อไว้เท่านั้น อาจไม่ใช่เรื่องใหญ่ แต่มีคนหวาดระแวงมากมายที่ปิดตัวพอร์ตทั่วทั้งองค์กร
Aaron Bertrand

จริงมันเป็นเพียงจุดเริ่มต้น พอร์ตที่ตั้งค่าโดยทั่วไปฉันพบลูกค้ามักจะมีเซิร์ฟเวอร์เหล่านั้นจดไว้ (ตระหนักถึงพวกเขา) ค้นหาวิธีนี้โดยBrian Kelleyแต่ยังไม่ได้ลอง

ฉันคิดว่าการรวมทั้งวิธีการรีจิสทรีและ win32_service WMI เป็นทางเลือกควรได้รับเซิร์ฟเวอร์ส่วนใหญ่แล้วการค้นหาด้วยตนเองของส่วนที่เหลือจะทำงานได้ ในฐานะที่เป็นผลข้างเคียงที่น่าพอใจฉันยังสามารถดึงข้อมูลบางอย่างเกี่ยวกับบริการที่กำลังทำงานอยู่ แต่ไม่จำเป็นต้องใช้เซิร์ฟเวอร์ที่ไม่อนุญาตให้ฉันเข้าถึงเป็นต้น
Elsimer

5

วิธีเดียวที่ฉันรู้ของการค้นพบกรณีข้ามสภาพแวดล้อมโดยไม่ทราบว่าทั้งหมดของเซิร์ฟเวอร์ที่เป็นเจ้าของที่เป็นไปได้และชื่อเฉพาะของพวกเขาจะมีการโทรไปยังSystem.Data.Sql.SqlDataSourceEnumerator.GetDataSources () วิธีนี้มาพร้อมกับเชิงอรรถมากมาย นี่คือตัวอย่างข้อมูลที่ดึงโดยตรงจากทรัพยากร MSDN นั้น:

เนื่องจากธรรมชาติของกลไกที่ใช้โดย SqlDataSourceEnumerator เพื่อค้นหาแหล่งข้อมูลบนเครือข่ายเมธอดจะไม่ส่งคืน รายการที่สมบูรณ์ของเซิร์ฟเวอร์ที่มีอยู่เสมอและรายการอาจไม่เหมือนกันในทุกการโทร หากคุณวางแผนที่จะใช้ฟังก์ชั่นนี้เพื่อให้ผู้ใช้เลือกเซิร์ฟเวอร์จากรายการตรวจสอบให้แน่ใจว่าคุณได้จัดหาตัวเลือกให้พิมพ์ชื่อที่ไม่ได้อยู่ในรายการเสมอในกรณีที่การแจงนับเซิร์ฟเวอร์ไม่ส่งคืนเซิร์ฟเวอร์ที่มีอยู่ทั้งหมด . นอกจาก นี้วิธีนี้อาจใช้เวลานานพอสมควรในการดำเนินการดังนั้นโปรดระมัดระวังในการโทรหาเมื่อประสิทธิภาพมีความสำคัญ

การโทรนั้นง่ายจาก PowerShell:

[System.Data.Sql.SqlDataSourceEnumerator]::Instance.GetDataSources()

วิธีการนั้นจะคืนDataTableวัตถุที่คุณสามารถจัดการได้


3

หากบริการเบราว์เซอร์ SQL เปิดใช้งานคุณสามารถสอบถามบริการสำหรับ SQL Instances ด้วยรหัส PowerShell ด้านล่าง มันใช้ commandlets ต่อไปนี้เพื่อดำเนินการค้นหา:

  • Get-SqlBrowserInstanceList
  • Get-SqlBrowserInstanceInfo
  • Get-SqlBrowserInstanceDac

    function Parse-ServerResponse([byte[]] $responseData)
    {
        [PSObject[]] $instances = @()
    
        if (($responseData -ne $null) -and ($responseData[0] -eq 0x05))
        {
            $responseSize = [System.BitConverter]::ToInt16($responseData, 1)
    
            if ($responseSize -le $responseData.Length - 3)
            {
                # Discard any bytes beyond the received response size. An oversized response is usually the result of receiving multiple replies to a broadcast request.
                $responseString = [System.Text.Encoding]::Default.GetString(($responseData | Select -Skip 3 -First $responseSize))
                $instanceResponses = $responseString.Split(@(";;"), [System.StringSplitOptions]::RemoveEmptyEntries)
    
                $instances = foreach ($instanceResponse in $instanceResponses)
                {
                    $instanceResponseValues = $instanceResponse.Split(";")
                    $instanceResponseHash = @{}
                    for ($index = 0; $index -lt $instanceResponseValues.Length; $index += 2)
                    {
                        $instanceResponseHash[$instanceResponseValues[$index]] = $instanceResponseValues[$index + 1]
                    }
    
                    New-Object PSObject -Property $instanceResponseHash
                }
            }
            else
            {
                Write-Warning "The response was too short. Expected $($responseSize) bytes but got $($responseData.Length - 3)."
            }
        }
    
        return ,$instances
    }
    
    function Parse-ServerResponseDac([byte[]] $responseData)
    {
        $dacPort = 0
    
        if (($responseData -ne $null) -and ($responseData[0] -eq 0x05))
        {
            $responseSize = [System.BitConverter]::ToUInt16($responseData, 1)
    
            if (($responseData.Length -eq 6) -and ($responseSize -eq 6))
            {
                if ($responseData[3] -eq 0x01)
                {
                    $dacPort = [System.BitConverter]::ToUInt16($responseData, 4)
                }
                else
                {
                    Write-Error "An unexpected protocol version was returned. Expected 0x01 but got $($requestData[3])."
                }
            }
            else
            {
                Write-Error "The response size was incorrect."
            }
        }
    
        return $dacPort
    }
    
    function Get-SqlBrowserInstanceList
    {
        <#
        .SYNOPSIS
        Gets the list of available SQL Instances on the server.
        .DESCRIPTION
        Gets the list of available SQL Instances on the server by querying the SQL Browser Service on port 1434.
        .EXAMPLE
        Get-SqlBrowserInstanceList servername
        .EXAMPLE
        Get-SqlBrowserInstanceList servername.dnsdomain.tld
        .EXAMPLE
        Get-SqlBrowserInstanceList $env:COMPUTERNAME
        .EXAMPLE
        Get-SqlBrowserInstanceList 192.168.1.255 -Broadcast
        .EXAMPLE
        Get-SqlBrowserInstanceList 255.255.255.255 -Broadcast
        .PARAMETER $ServerName
        The name or IP Address of the server.
        .PARAMETER $Broadcast
        If the broadcast switch is specified, the query will be sent as a broadcast and may receive replies from multiple hosts; otherwise, the query is sent to a single server.
        #>
        [CmdletBinding(SupportsShouldProcess = $False)]
        param
        (
            [Parameter(Mandatory = $True, ValueFromPipeLine = $True)]
            [string] $ServerName,
            [switch] $Broadcast
        )
    
        process
        {   
            [System.Net.IPAddress] $ipAddress = [System.Net.Dns]::GetHostAddresses($serverName) | Select -First 1
            $parsedResponses = @()
    
            if ($ipAddress -ne $null)
            {
                [System.Net.IPEndPoint] $localIPEndPoint = New-Object System.Net.IPEndPoint([System.Net.IPAddress]::Any, 0)
                [System.Net.IPEndPoint] $remoteIPEndPoint = New-Object System.Net.IPEndPoint($ipAddress, 1434)
    
                if ($ipAddress -eq [System.Net.IPAddress]::Broadcast)
                {
                    $Broadcast = $true
                }
    
                [System.Net.Sockets.UdpClient] $receiver = New-Object System.Net.Sockets.UdpClient
                $receiver.Client.ReceiveTimeout = 30000
    
                [byte] $queryMode = 0x03
                $sleepDuration = 1
                [System.Net.Sockets.UdpClient] $sender = $null
    
                if ($Broadcast -eq $true)
                {
                    Write-Verbose "Using broadcast mode."
                    $queryMode = 0x02
                    $sleepDuration = 30
    
                    # Set the receiver to allow another client on the same socket.
                    $receiver.Client.SetSocketOption([System.Net.Sockets.SocketOptionLevel]::Socket, [System.Net.Sockets.SocketOptionName]::ReuseAddress, $true)
                    $receiver.Client.Bind($localIPEndPoint)
    
                    # Because broadcasting from this UdpClient instance causes the underlying socket to be unable to receive normally, a separate sender must be bound to the same socket as the receiver.
                    # NOTE: Windows Firewall does not view a reused socket as being part of the same conversation. If Windows Firewall is active, this requires special firewall rules to work.
                    $sender = New-Object System.Net.Sockets.UdpClient
                    $sender.EnableBroadcast = $Broadcast
                    $sender.Client.SetSocketOption([System.Net.Sockets.SocketOptionLevel]::Socket, [System.Net.Sockets.SocketOptionName]::ReuseAddress, $true)
                    $sender.Client.Bind($receiver.Client.LocalEndPoint);
                }
                else
                {
                    $sender = $receiver
                    $receiver.Client.Bind($localIPEndPoint)
                }
    
    
                $responses = @{}
    
                try
                {
                    # Send the broadcast.
                    Write-Verbose "Sending request to $($ipAddress)..."
                    $sender.Connect($remoteIPEndPoint)
                    $bytesSent = $sender.Send(@($queryMode), 1)
    
                    # Wait to give responses time to arrive.
                    Sleep $sleepDuration
    
                    do
                    {
                        [System.Net.IPEndPoint] $responderIPEndPoint = $null
                        $response = $receiver.Receive([ref] $responderIPEndPoint)
                        $responder = $responderIPEndPoint.ToString()
    
                        if ($responses.Contains($responder))
                        {
                            $responses[$responder] += $response
                        }
                        else
                        {
                            $responses.Add($responder, $response)
                        }
                    } while ($receiver.Available -gt 0)
                }
                finally
                {
                    if ($sender -ne $receiver)
                    {
                        $sender.Close()
                        $sender.Dispose()
                    }
    
                    $receiver.Close()
                    $receiver.Dispose()
                }
    
                foreach ($responseItem in $responses.GetEnumerator())
                {
                    Write-Verbose "Parsing the response from $($responseItem.Name)..."
                    $parsedResponse = Parse-ServerResponse $responseItem.Value
                    $parsedResponses += $parsedResponse
                    Write-Verbose ($parsedResponse | ft ServerName, InstanceName, tcp, np, Version, IsClustered -AutoSize |Out-String)
                }
            }
    
            return $parsedResponses
        }
    }
    
    function Get-SqlBrowserInstanceInfo
    {
        <#
        .SYNOPSIS
        Gets information about the specified SQL Instance from the server.
        .DESCRIPTION
        Gets information about the specified SQL Instance from the server by querying the SQL Browser Service on port 1434.
        .EXAMPLE
        Get-SqlBrowserInstanceInfo servername instancename
        .EXAMPLE
        Get-SqlBrowserInstanceInfo servername.dnsdomain.tld instancename
        .EXAMPLE
        Get-SqlBrowserInstanceInfo $env:COMPUTERNAME
        .PARAMETER $ServerName
        The name or IP Address of the server.
        .PARAMETER $InstanceName
        The name of the SQL Instance.    #>
        [CmdletBinding(SupportsShouldProcess = $False)]
        param
        (
            [Parameter(Mandatory = $True, ValueFromPipeLine = $True)]
            [string] $ServerName,
            [Parameter(Mandatory = $True, ValueFromPipeLine = $False)]
            [string] $InstanceName
        )
    
        process
        {   
            $instances = @()
            [System.Net.IPAddress] $ipAddress = $null
    
            $ipAddress = [System.Net.Dns]::GetHostAddresses($serverName) | Select -First 1
    
            if ($ipAddress -ne $null)
            {
                [System.Net.IPEndPoint] $ipEndPoint = New-Object System.Net.IPEndPoint($ipAddress, 1434)
                [System.Net.Sockets.UdpClient] $udpClient = New-Object System.Net.Sockets.UdpClient
                $udpClient.Client.ReceiveTimeout = 10000
    
                $instanceNameData = [System.Text.Encoding]::Default.GetBytes($instanceName)
                [byte[]] $requestData = @(0x04) + $instanceNameData + 0x00
                [byte[]] $responseData = $null
    
                try
                {
                    $udpClient.Connect($ipEndPoint)
    
                    $bytesSent = $udpClient.Send($requestData, $requestData.Length)
    
                    $responseData = do
                    {
                        $udpClient.Receive([ref] $ipEndPoint)
                    } while ($udpClient.Available -gt 0)
                }
                finally
                {
                    $udpClient.Close()
                    $udpClient.Dispose()
                }
    
                $instances = Parse-ServerResponse $responseData
            }
    
            return $instances
        }
    }
    
    function Get-SqlBrowserInstanceDac
    {
        <#
        .SYNOPSIS
        Gets the Dedicated Administrator Connection port number for the specified SQL Instance on the server.
        .DESCRIPTION
        Gets the Dedicated Administrator Connection port number for the specified SQL Instance on the server by querying the SQL Browser Service on port 1434.
        .EXAMPLE
        Get-SqlBrowserInstanceDac servername instancename
        .EXAMPLE
        Get-SqlBrowserInstanceDac servername.dnsdomain.tld instancename
        .EXAMPLE
        Get-SqlBrowserInstanceDac $env:COMPUTERNAME instancename
        .PARAMETER $ServerName
        The name or IP Address of the server.
        .PARAMETER $InstanceName
        The name of the SQL Instance.
        #>
        [CmdletBinding(SupportsShouldProcess = $False)]
        param
        (
            [Parameter(Mandatory = $True, ValueFromPipeLine = $True)]
            [string] $ServerName,
            [Parameter(Mandatory = $True, ValueFromPipeLine = $False)]
            [string] $InstanceName
        )
    
        process
        {   
            [System.UInt16] $dacPort = 0
            [System.Net.IPAddress] $ipAddress = $null
    
            $ipAddress = [System.Net.Dns]::GetHostAddresses($serverName) | Select -First 1
    
            if ($ipAddress -ne $null)
            {
                [System.Net.IPEndPoint] $ipEndPoint = New-Object System.Net.IPEndPoint($ipAddress, 1434)
                [System.Net.Sockets.UdpClient] $udpClient = New-Object System.Net.Sockets.UdpClient
                $udpClient.Client.ReceiveTimeout = 30000
    
                $instanceNameData = [System.Text.Encoding]::Default.GetBytes($instanceName)
                [byte[]] $requestData = @(0x0F) + 0x01 + $instanceNameData + 0x00
                [byte[]] $responseData = $null
    
                try
                {
                    $udpClient.Connect($ipEndPoint)
    
                    $bytesSent = $udpClient.Send($requestData, $requestData.Length)
    
                    $responseData = do
                    {
                        $udpClient.Receive([ref] $ipEndPoint)
                    } while ($udpClient.Available -gt 0)
                }
                finally
                {
                    $udpClient.Close()
                    $udpClient.Dispose()
                }
    
                $dacPort = Parse-ServerResponseDac($responseData)
            }
    
            return $dacPort
        }
    }

2

อีกวิธีหนึ่งในการระบุอินสแตนซ์ของ SQL ที่เป็นไปได้คือดูที่ Service Principle Names (SPNs) ที่อยู่ใน Active Directory เมื่อคุณเชื่อมต่อกับ SQL Server จากระยะไกลด้วย Windows Authentication SPN จะถูกใช้ในกระบวนการตรวจสอบความถูกต้อง การปรากฏตัวของ SPN ไม่ได้หมายความว่าเซิร์ฟเวอร์ / อินสแตนซ์นั้นอยู่ที่นั่นและกำลังทำงานอยู่ แต่จะให้รายการของอินสแตนซ์ที่เป็นไปได้ซึ่งคุณได้พบว่าครอบคลุมวิธีการอื่น ๆ

เพื่อทำให้ชีวิตง่ายขึ้นฉันใช้ Get-SPN cmdlet จาก: https://gallery.technet.microsoft.com/scriptcenter/Get-SPN-Get-Service-3bd5524a

ดาวน์โหลดสคริปต์ Get-SPN.ps1 บันทึกลงใน C: \ powershell_scripts \ Get-SPN.ps1 และเรียกใช้สิ่งต่อไปนี้ใน PowerShell:

. "C:\powershell_scripts\Get-SPN.ps1"
Get-SPN -ServiceClass MSSQLSvc

(เห็นได้ชัดว่าคุณสามารถบันทึกสคริปต์ไปยังตำแหน่งอื่นเพียงแค่อัปเดตบรรทัดแรกตามต้องการ)

นี่จะแสดงรายการ SQL Server SPNs ทั้งหมดบนโดเมนปัจจุบันรวมถึง "ข้อมูลจำเพาะ" ซึ่งเกี่ยวข้องกับพอร์ต / อินสแตนซ์ของบริการ


ฉันสังเกตเห็นว่าเครื่อง SQL Server ของเราส่วนใหญ่ไม่สามารถรับ SPN ได้ (หรือคำเตือนบางอย่างในบันทึกการบำรุงรักษา) พวกเขาจะยังคงปรากฏตัวโดยใช้สคริปต์นั้นหรือไม่
Elsimer

นั่นเป็นเพราะบริการนี้ทำงานในฐานะผู้ใช้ที่ไม่ใช่ผู้ดูแลโดเมนหรือระบบภายในเครื่อง (จำเป็นต้องสร้าง SPN) ผู้ดูแลโดเมนอาจเพิ่ม SPNs โดยใช้ยูทิลิตี้ SetSPN และบัญชีผู้ดูแลโดเมนของพวกเขาเพื่อให้การตรวจสอบโดเมนทำงานอย่างถูกต้องสำหรับเครื่องเหล่านี้ มีแนวโน้มใช่
Matt

0

รับบริการ - ชื่อคอมพิวเตอร์ * MSSQL * | โดยที่-Object {$ _. status -eq "Running"}

ที่ควรได้รับการตั้งชื่อและอินสแตนซ์เริ่มต้น เพียงทำซ้ำรายการเครื่องของคุณ ฯลฯ


-4

เพิ่งลองสิ่งนี้: [System.Data.Sql.SqlDataSourceEnumerator] :: Instance.GetDataSources ()

ข้อมูลกลับมาไม่มาก แต่ตรวจพบเซิร์ฟเวอร์ sql ทั้งหมดที่ฉันใช้ในสภาพแวดล้อม VM


6
วิธีการนั้นรวมอยู่ในคำตอบของ Thomas Stringer แล้ว
MDCCL
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.