【发布时间】:2014-09-23 15:44:22
【问题描述】:
我有一个 .bat 文件,它可以毫无问题地执行一系列事物。它进入powershell执行行: PowerShell.exe "Y:\Data\FS01\NoTouch_Deploy.ps1"
我收到以下错误: 警告:无法加载“SQLAS”扩展:尝试管理服务时 SMO 中出现异常。 --> 未能为此请求检索数据。 --> 无效的类
当我通过 GUI 运行相同的脚本时,它运行没有问题。我还尝试在同一位置运行一个简单的 Powershell 脚本(测试脚本只是抛出一个 Windows 消息框,让我知道它正在打开和执行)这也可以。但是一旦我添加了常规的 .ps1 并从 .bat 文件运行它,我就会收到这个错误。该脚本包含在下面。脚本的快速摘要:它设置了一些变量,创建了 2 个函数(BCP,以及用于错误捕获的日志写入)重命名一些表并触发 SQL 存储过程。然后执行 BCP 函数将数据从服务器移动到服务器,然后再执行一个过程。
cls
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
## TEST MSGBOX## [System.Windows.Forms.MessageBox]::Show("We are proceeding with next step." , "Status")
$ErrorActionPreference = "stop"
[Void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO")
[Void][System.Reflection.Assembly]::LoadWithPartialName("System.Data")
Add-PsSnapin sqlserverprovidersnapin100 -ErrorAction SilentlyContinue
Add-PsSnapin sqlservercmdletsnapin100 -ErrorAction SilentlyContinue
Import-Module SQLPs -DisableNameChecking -ErrorAction SilentlyContinue
#Import-Module SQLAS -DisableNameChecking -ErrorAction SilentlyContinue
Set-Location 'C:\'
# Set Variables (Make table driven for final tool creation)
$SourceServer = "DevServ"
$SourceDB = "DevDB"
$SourceObject = "DevTable"
$TargServer = "ProdServ"
$TargDB = "ProdDB"
$TargObject = "ProdTable"
$ContainerDB = 'MainDB'
################################################################################################################
## Begin Function LogWrite ##
##################################################################################################### ###########
Function LogWrite ()
{
Param
(
[string]$LogStr,
[string]$Table,
[string]$Server,
[string]$DataBase
)
Trap{continue}
#$DateTime = Get-Date -UFormat "%Y:%MM:%D:%H:%M:%S"
$LogInsQuery = "INSERT INTO dbo.Deploy_LOG ([TableName], [LOGTEXT],[DateStamp]) VALUES ('" + $Table + "', '" + $LogStr + "',getdate())"
Invoke-Sqlcmd -ServerInstance $SServer -Database $SDB -Query $LogInsQuery
}
################################################################################################################
## Begin Function BCP
################################################################################################################
Function BCP ()
{
Param
(
[string]$SourceServer,
[string]$SourceDB,
[string]$SourceObject,
[string]$TargServer,
[string]$TargDB,
[string]$TargObject
)
$NewServer
Try
{
$SourceCon = New-Object Data.SqlClient.SqlConnection
$SourceCon.ConnectionString = "Data Source=$SourceServer;DataBase=$SourceDB;Integrated Security=True"
Logwrite "$TargObject -- Beginning BCP transfer process" $SourceObject
$TargCon = New-Object Data.SqlClient.SqlConnection
$TargCon.ConnectionString = "Data Source=$TargServer;DataBase=$TargDB;Integrated Security=True"
$TargCon.open()
#[long]$StartCount = (Invoke-Sqlcmd -ServerInstance $SourceServer -Query "SELECT COUNT(*) as 'Ct' FROM $TargDB.dbo.$TargObject")[0]
$bcp = New-Object Data.SqlClient.SqlBulkCopy($TargCon.ConnectionString, [System.Data.SqlClient.SqlBulkCopyOptions]::KeepIdentity)
$FieldsServer = New-Object "Microsoft.SqlServer.Management.SMO.Server" $TargServer
$DevServer = New-Object "Microsoft.SqlServer.Management.SMO.Server" $SourceServer
$SelectString = 'SELECT '
$DevServer.Databases[$TargDB].Tables | ?{$_.name -eq $TargObject} | %{$_.Columns | %{$SelectString += "[$($_.name)],"}}
$SelectString = $SelectString.Substring(0, ($SelectString.Length - 1)) # Remove the trailing comma
$SelectString += " FROM dbo.$SourceObject"
$SourceCon.open()
$SqlCmd = New-Object "Data.SqlClient.SqlCommand" -ArgumentList $SelectString, $SourceCon
[Data.IDataReader]$DataReader = $SqlCmd.ExecuteReader()
$bcp.BulkCopyTimeout = 0
$bcp.DestinationTableName = "dbo.$TargObject"
$bcp.WriteToServer($DataReader)
$SqlCmd = $null
$DataReader = $null
$SourceCon.Close()
$bcp.Close()
$TargCon.Close()
LogWrite "$TargObject -- Transfer complete" $SourceObject;
}
Catch
{
LogWrite "ERROR in BCP Subroutine -- $_" $SourceObject;
}
}
################################################################################################################
## Begin main code section end of functions
################################################################################################################
Try
{
$SqlQuery = "SP_Rename 'TableName','TableName_Deploy'"
Invoke-Sqlcmd -ServerInstance $SServer -Database $SDB -Query $SqlQuery
$SqlQuery =""
# runs the Sproc on the FLD server to make sure that the _Deploy table exists, is empty and is indexed.
$DeployTableSproc = "EXECUTE [dbo].[SP_NoTouch_Staging_Build]"
Invoke-Sqlcmd -ServerInstance $TargServer -Database $ContainerDB -Query $DeployTableSproc
# Runs the BCP process to copy the records to the Feild into the new prepared table.
BCP $SServer $SDB $SourceObject $TargServer $TargDB $TargObject
$SqlQuery = "EXECUTE [MainDB].[dbo].[Notify_NoTouch] @EmailType = 6"
Invoke-Sqlcmd -ServerInstance $SServer -Database $SDB -Query $SqlQuery
$SqlQuery =""
LogWrite "No touch table transfer complete Table renamed and indexed" $SourceObject;
}
Catch
{
LogWrite "ERROR in Transfer process" $SourceObject;
}
我尝试添加 #Import-Module SQLAS -DisableNameChecking -ErrorAction SilentlyContinue 它没有帮助。有任何想法吗?谢谢
【问题讨论】:
-
添加
#Import-Module什么也没做,因为#表示后面的所有内容都是注释 - 它永远不会被执行。但在 v3 和更新版本下,这并不重要,因为模块会在需要时自动导入。 -
我在运行后将其注释掉,但它什么也没做。抱歉,我把它贴在这里时留下了评论。我想我还在 V2 上
-
批处理文件是如何运行的?您是手动运行它还是可能在不同帐户下运行的计划任务?您如何通过 ISE 或控制台在批处理文件之外手动运行脚本?您是否会在 ISE 配置文件中自动加载未为控制台加载的内容?
-
为了对此进行测试,我只需单击一个 .bat 文件即可执行。它最终将由任务调度程序运行,但使用我的配置文件。在 .bat 文件之外,我使用 powerGUI 来运行 .ps1 脚本。我还没有通过控制台尝试过,但我现在就去做。我不确定您在我的 ISE 配置文件中自动加载内容是什么意思..
-
加载 PowerShell 并输入
notepad $profile并回车。看看那里是否列出了东西。您应该在控制台和 PowerGUI 中执行相同的操作(为了保持一致性,我假设它使用相同的函数来映射其配置文件)。只要您启动 PowerShell,它就会运行。我知道我的 ISE 配置文件将 consolepanelbackgroundcolor 设置为黑色,更改当前文件夹,并在我启动它时加载 3 个模块。
标签: windows powershell batch-file