【问题标题】:Why working directory is changing when executing Invoke-sqlcmd?为什么执行 Invoke-sqlcmd 时工作目录会发生变化?
【发布时间】:2014-12-03 13:51:56
【问题描述】:

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

我们正在使用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 server 2012 执行它。

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

【问题讨论】:

  • 该代码看起来不完整。你在什么时候写日志?
  • @arco444 更新了 sn-p
  • 所以它在尝试写入日志时失败了,但你没有在实际发生的地方包含 LogWrite 函数。这肯定是脚本中最相关的部分吗?

标签: powershell sql-server-2012


【解决方案1】:

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

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

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

要么解决这个问题,要么通过在命令中考虑目录更改来解决问题。

【讨论】:

    【解决方案2】:

    我可能会遇到类似的情况。我的代码看起来像这样,例如在 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

    谢谢。

    【讨论】:

      猜你喜欢
      • 2018-11-23
      • 1970-01-01
      • 2021-12-18
      • 2017-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-23
      • 2015-09-14
      相关资源
      最近更新 更多