在 PowerShell 中针对 WID 远程运行 sqlcmd

Posted

技术标签:

【中文标题】在 PowerShell 中针对 WID 远程运行 sqlcmd【英文标题】:Running sqlcmd against the WID in PowerShell remotely 【发布时间】:2021-08-06 23:32:01 【问题描述】:

我正在与 WSUS 斗争并尝试设置一个脚本来管理远程站点中多台服务器上的 SUSDB 维护,我们有多个版本和多个操作系统的服务器,所以它变得有点复杂,较新的 ( post 2008R2) 没有问题,但是,Server 2008s 有一个问题:

我在本地或在交互式远程会话中运行它,它按预期工作,但如果我嵌套调用命令以在远程会话中运行它,如下所示,它会出现以下错误:

HResult 0x2,级别 16,状态 1 命名管道提供程序:无法打开与 SQL Server [2] 的连接。 Sqlcmd:错误:Microsoft SQL Server Native Client 10.0:建立与 SQL Server 的连接时发生与网络相关或特定于实例的错误。服务器未找到或无法访问。检查实例名称是否正确以及 SQL Server 是否配置为允许远程连接。有关详细信息,请参阅 SQL Server 联机丛书。。

Sqlcmd:错误:Microsoft SQL Server Native Client 10.0:登录超时已过期

我已经四处搜寻了几天并尝试了所有我能想到的排列,但这是我所拥有的:

$SQLPath = "C:\Users\<username>\Documents\SQL Server Management Studio\"
$SQLfile = "SUSDB-ReIndex.sql"
$WsusSvrs = ("WSUS-Site1","WSUS-Site7","WSUS-Site13","WSUS-Site14","WSUS-Site15")
$ErrorActionPreference = "Stop"
$results = @()

Foreach ($WSUSSvr in $WSUSSvrs) 
    Try 
        $sess = New-PSSession -ComputerName $WSUSSvr -EnableNetworkAccess -ErrorAction Stop
    
    Catch 
        continue;
     

    $output = Invoke-Command -Session $sess -ScriptBlock 
        If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))    
            $arguments = "& '" + $myinvocation.mycommand.definition + "'"
            Start-Process powershell -Verb runAs -ArgumentList $arguments
            Break
         

        If((Get-Command SQLcmd.exe -ErrorAction SilentlyContinue)-eq "") 
            $NoSQLCmd = new-object System.IO.FileNotFoundException("SQLcmd is not Installed on this machine, please install the appropriate version and try again")
            Throw $NoSQLCmd
        

        $Output = New-Object psobject
        $OSVerStr = (Gwmi win32_operatingsystem).version.split(".")
        [single]$OS = [convert]::ToSingle(($OSVerStr[0],$OSVerStr[1] -join "."))
        $Output | Add-Member -MemberType NoteProperty -Name OSVer -Value $OS

        if ($OS -gt 6.1) 
            $conStr = "\\.\pipe\Microsoft##WID\tsql\query"
        
        Else 
            $conStr = 'np:\\.\pipe\MSSQL$MICROSOFT##SSEE\sql\query'
        

        if(Test-Path "$using:SQLPath\$Using:SQLfile") 
            $cmd = "sqlcmd.exe -S $ConStr -i '$Using:SQLPath\$Using:SQLfile' -d 'SUSDB' -E -o 'C:\temp \$Using:WSUSSvr-reindexout.txt'"
            Invoke-Expression $cmd
            $output | Add-Member -MemberType NoteProperty -Name Message -Value "done"
        
        else 
            $output | Add-Member -MemberType NoteProperty -Name Message -Value "Unable to find $Using:sqlfile"
        
        $Output
     -ArgumentList $SQLPath,$SQLfile,$WSUSSvr

    $results += $output

    if(test-path "\\$wsussvr\C$\temp\$WSUSSvr-reindexout.txt") 
        cp "\\$wsussvr\C$\temp\$WSUSSvr-reindexout.txt" "D:\wsus-reports\" -Force
    

    If( $sess.State -eq "Opened" )  Remove-PSSession $sess 


$results | ft

我知道我们现在应该拍摄 2008 年的盒子,但是有一个利基产品供应商和更换盒子的一些预算问题。

【问题讨论】:

【参考方案1】:

在第 35 行,我看到以下内容

    Else 
        $conStr = 'np:\\.\pipe\MSSQL$MICROSOFT##SSEE\sql\query'
    

您可以尝试在没有 np: 的情况下运行它吗?

    Else 
        $conStr = '\\.\pipe\MSSQL$MICROSOFT##SSEE\sql\query'
    

【讨论】:

那是原始配置,它没有任何区别,因为它无论如何都会调用命名管道提供者

以上是关于在 PowerShell 中针对 WID 远程运行 sqlcmd的主要内容,如果未能解决你的问题,请参考以下文章

powershell 在PowerShell远程处理上运行iisreset

在不提示的情况下在 Powershell 中获取当前用户的凭据对象

在远程计算机运行PowerShell命令

在 C# 中使用不同的凭据调用远程 powershell 脚本

通过 Powershell 远程 TFS 签入

在远程机器上启动应用程序并保持运行,powershell 脚本不应等待进程完成