PowerShell invoke-sqlcmd Get-ChildItem:无法调用方法。提供者不支持使用过滤器

2023-12-14

使用 invoke-sqlcmd 将行插入表时出现奇怪的错误。如果执行一次,整个脚本可以完美运行,但如果我第二次运行它,它就会失败并显示错误消息:Get-ChildItem:无法调用方法。该提供商不支持使用过滤器。我测试了代码并注释掉了invoke-sqlcmd行,并且可以多次运行它而不会出现任何错误。我将invoke-sqlcmd放入一个函数中,但它仍然出错,并且在第一次成功运行后,它也会在PS命令行中失败。

Clear-Host
$ErrorActionPreference = 'Stop'

function Update-SQL
{
    invoke-sqlcmd -query $strSQLInsert -server SXLSV-LEAPDBD1 -database DTCS_DV
}

$files = Get-ChildItem '\\pcslog1011\dtcs\ContractEmailNotes\' -Filter '*.txt' | Where-Object {$_.LastWriteTime -ge '08/22/2016 00:00:00' -and $_.LastWriteTime -le '08/22/2016 23:59:59'} | sort-object -Descending

for ($i=0; $i -lt $files.Count; $i++) 
{
    $SNAC_CNTR_ID = $files[$i].BaseName.Substring(0,6)
    $SNAC_MODIFIED = '{0:yyyy-MM-dd HH:mm:ss}' -f ($files[$i].LastWriteTime)

    $reader = [System.IO.File]::OpenText($files[$i].FullName)
    $lineCnt = 0
    $SNAC_ACTION = ''
    for() 
    {
        $lineCnt += 1 
        $line = $reader.ReadLine()
        if ($line -eq $null) {break}
        if ($lineCnt -eq 4)
        {
            if ($line.Contains('AMENDED') -eq $True)
            {
                $SNAC_ACTION = 'AMENDED'
            }
            elseif ($line.Contains('DEAL CHANGED') -eq $True)
            {
                $SNAC_ACTION = 'CHANGED'
            }
            else
            {
                $SNAC_ACTION = 'NEW'
            }
        }
    }
    $reader.Close()

    write-host $SNAC_CNTR_ID $SNAC_MODIFIED $SNAC_ACTION

    $strSQLInsert = "INSERT INTO CQT_CONTRACT_SOX_NAC_LIST (SNAC_CNTR_ID, SNAC_MODIFIED, SNAC_ACTION, SNAC_UPDATED_BY, SNAC_UPDATED_ON) VALUES ('" + $SNAC_CNTR_ID + "', '" + $SNAC_MODIFIED + "', '" + $SNAC_ACTION + "', Default, Default)"

    Update-SQL $strSQLInsert
}

exit

我知道这是一个相当旧的线程,但我遇到了类似的问题,导致我进入此页面。以下是为我解释和解决问题的链接。

PowerShell Invoke-Sqlcmd 切换到 sqlps 会话
卡在Powershell sqlserver中

简短回答

默认情况下,SQLPS 提供程序无法识别 UNC 路径。您可以使用特定的文件系统提供程序为 UNC 路径添加前缀:

Get-ChildItem Microsoft.PowerShell.Core\FileSystem::\\pcslog1011\dtcs\ContractEmailNotes\
-Filter '*.txt'

或者在加载 SQLPS 模块后将工作目录切换回默认目录,方法是将其添加到脚本顶部:

Push-Location
Import-Module SQLPS -DisableNameChecking
Pop-Location

长答案

该问题似乎是由于 PowerShell 将工作目录从默认值切换到 SQLPS 提供程序的工作目录以及 SQLPS 提供程序无法识别 UNC 路径(没有任何鼓励)这一事实造成的。

正常的 PowerShell 提示符如下所示:

PS C:\Users\foobar>

当您在 SQLPS 提供程序的目录结构中工作时,它会看起来像下面的提示(更多关于这意味着什么here):

PS SQLSERVER:\>

无论如何,脚本第一次调用 Get-ChildItem 时,很可能是从默认 PowerShell 工作目录(可以理解 UNC 路径)的上下文中执行此操作。但是,调用 Invoke-Sqlcmd 会加载 SQLPS 模块,该模块会将工作目录更改为无法识别 UNC 路径的提供程序的目录。因此,下次调用 Get-ChildItem 时,将从提供程序的目录结构中执行此操作,从而引发错误。该问题实际上与过滤器支持无关。

其他人发现的解决此问题的两种方法是在 UNC 路径前面加上文件系统提供程序,以便 SQLPS 可以解析它(source):

Get-ChildItem Microsoft.PowerShell.Core\FileSystem::\\pcslog1011\dtcs\ContractEmailNotes\ -Filter '*.txt'

或者在 SQLPS 模块加载后切换回默认工作目录。最好的方法可能是在脚本开头显式加载 SQLPS 提供程序并在前后添加 Push/Pop-Location cmdlet(无需对原始脚本进行其他更改)。

Push-Location
Import-Module SQLPS -DisableNameChecking
Pop-Location

最后要注意的两件事。首先,我在大约 100 台具有不同操作系统版本、补丁级别和 PowerShell 版本的服务器上运行了我的代码。我仅在某些运行 PowerShell 5.1 的服务器上看到此问题。其他 5.1 服务器都很好。

其次,这整个事件显然可以通过简单地使用更新的 SQLServer 提供程序来避免,该提供程序应该取代 SQLPS。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PowerShell invoke-sqlcmd Get-ChildItem:无法调用方法。提供者不支持使用过滤器 的相关文章

随机推荐