为什么工作目录在执行 Invoke-sqlcmd 时发生更改



我正在尝试搜索数据库中是否有特定的机器名称,如果是,我们将用新的机器名称替换。

我们正在使用Powershell

 Add-pssnapin sqlserverprovidersnapin100 -ErrorAction SilentlyContinue
    Add-pssnapin sqlservercmdletsnapin100 -ErrorAction SilentlyContinue
    $SelectQuery = "SELECT [$columnName] FROM [$DatabaseName].[dbo].[$TableName] Where [$columnName] is not null;"
    try {
          $Qresult= Invoke-sqlcmd -query $SelectQuery -Database $DatabaseName -ServerInstance $srvInstance -Verbose
          $Qresult = $Qresult| % { $_.$columnName+"`n" 
           #check whether the Machine Name is found if the column value is processed in URL format
            $IsOldFoundFromURL=TestOldMachineFromURL $Qresult $OldMachineName
            #check whether the Machine Name is found if the column value is processed in Connection string format
            $IsOldFoundFromConn=TestOldMachineFromconnstring $Qresult $OldMachineName
            If ( $IsOldFoundFromURL -or  $IsOldFoundFromConn ) {
                    LogWrite "Columns Name before changing: $columnName "
                    LogWrite "$Qresult"
            }
            Else {
                    LogWrite "OldMachine name is not found in DB"
                    Return
            }
     }
     catch {
            Write-error "Error occured when executing sql $SelectQuery"
            LogWrite $Error[0]
        }

一切都很好.但是在执行 Invoke-sqlcmd 时,驱动器号将更改为 SQLServer:\这令人惊讶。

我在 Windows 2012

R2 机器上运行它,并对 sQL 服务器 2012 执行此操作。

问题是当工作目录更改我们的脚本失败时,我们正在当前脚本路径中写入日志文件,当脚本路径更改为 SQLserver:\ 时,无法创建日志文件并失败。

此问题

作为在开始时运行代码的Add-pssnapin sqlserverprovidersnapin100 -ErrorAction SilentlyContinue部分的一部分而发生。我不确定为什么这样做,但我知道当我在运行 MS SQL 2012 的网络中的计算机上运行类似的命令 ( Import-Module 'sqlps' -DisableNameChecking ) 时,它会将文件系统位置从任何位置更改为SQLSERVER:>位置 - 我认为这是因为它希望您开始使用 SQL Server 实例中的命令。

要解决此问题,您可以执行Push-LocationPop-Location命令以移回原始位置,如下所示;

C:Usersfoo.bar> Push-Location
C:Usersfoo.bar> Add-pssnapin sqlserverprovidersnapin100 -ErrorAction SilentlyContinue
SQLSERVER:> Add-pssnapin sqlservercmdletsnapin100 -ErrorAction SilentlyContinue
SQLSERVER:> Pop-Location
C:Usersfoo.bar> _

要么这样,要么通过考虑命令中目录的更改来克服问题。

我可能会在类似的情况下运行。我的代码看起来像这样,例如在 D:\test\myscript.ps1:

Set-Location $PSScriptRoot
#pos1: before invoke-sqlcmd
Get-Location # will return D:test
Invoke-Sqlcmd ...
#pos2: afer invokes-sqlcmd
Get-Location 
Test-Path -path <UNC-Path> # the <UNC-Path> absolutely exists.

我的问题:

  • 当我在 PowerShell 会话中执行此脚本时,Test-Path返回 True。

  • 当我将此脚本配置为在同一服务器中作为 SQL Server 代理作业步骤执行时,Test-Path始终返回 False。我的步骤配置是

    powershell -file "D:\test\myscript.ps1"

在 SQL Server 代理作业步骤的日志中,pos2 处的Get-Location返回"SQLSERVER:\"

我在Invoke-SqlCmd后使用 Set-Location $PScriptRoot 解决了问题,Test-Path按预期返回 True。

因此,任何人都可以解释为什么Invoke-SqlCmd更改位置以及这如何影响Test-Path

谢谢。

最新更新