Invoke-SQLcmd:'@'附近的语法不正确。 Msg 102,Level 15,State 1,Procedure,Line 5

问题描述 投票:0回答:2

我试图获取远程服务器硬件规格,并希望将它们插入到也位于远程服务器上的SQL Server表中。我收到以下错误。

Invoke-SQLcmd:'@'附近的语法不正确。 Msg 102,Level 15,State 1,Procedure,Line 5。

码:

$ServerName = "SQLSRV"
$DatabaseName = "Automation"
$conn=New-Object System.Data.SqlClient.SQLConnection
$ConnectionString =  "Server = $SQLServer; Database = $SQLDBName; 
User ID= automationusr; Password= Password@SQL" 
$conn.ConnectionString=$ConnectionString
$conn.Open()
$ServerListFile = "C:\Scripts\ServerList.txt"
$ServerList = Get-Content $ServerListFile -ErrorAction SilentlyContinue  
$Result = @()  
ForEach($computername in $ServerList)  
{ 

$AVGProc = Get-WmiObject -computername $computername win32_processor |  
Measure-Object -property LoadPercentage -Average | Select Average 
$OS = gwmi -Class win32_operatingsystem -computername $computername | 
Select-Object @{Name = "MemoryUsage"; Expression = {“{0:N2}” -f ((($_.TotalVisibleMemorySize - $_.FreePhysicalMemory)*100)/ $_.TotalVisibleMemorySize) }} 
$vol = Get-WmiObject -Class win32_Volume -ComputerName $computername -Filter "DriveLetter = 'C:'" | 
Select-object @{Name = "C PercentFree"; Expression = {“{0:N2}” -f  (($_.FreeSpace / $_.Capacity)*100) } } 
$result += [PSCustomObject] @{  
ServerName = "'$computername'" 
CPULoad = "'$($AVGProc.Average)%'" 
MemLoad = "'$($OS.MemoryUsage)%'" 
CDrive = "'$($vol.'C PercentFree')%'" 
QDate = "'$(Get-Date -Format "yyyyMMdd")'"
    } 

    Foreach($Entry in $Result)  
{
$QDate=$TESTTB01.Date
$ServerName=$TESTTB01.SName
$CPULoad=$TESTTB01.ACPU
$MemLoad=$TESTTB01.MEMU
$CDrive=$TESTTB01.DRVC

$insertquery="
INSERT INTO [dbo].[TESTTB01]
   (Date,SName,ACPU,MEMU,DRVC)
     VALUES
   ('['$ENTRY.QDate']','['$ENTRY.ServerName']','['$Entry.CPULoad']','['$Entry.MemLoad']','['$Entry.CDrive']')
GO
"
Invoke-SQLcmd -ServerInstance 'SQLSRV' -query $insertquery -U automationusr -P Password@SQL -Database Automation
}
}

我想创建一个任务,可以执行代码获取远程服务器的配置,并在每15分钟后在SQL Server表中插入变量

sql sql-server powershell
2个回答
0
投票
  • 在可扩展字符串("...")中,您不能直接嵌入属性访问表达式,如$ENTRY.QDate;相反,你必须将它们包含在$(...)中: 有关PowerShell字符串扩展规则的概述,请参阅this answer。 如果没有封闭的$(...)$ENTRY将整体字符串化,在[pscustomobject]实例的情况下会导致类似哈希表的字符串表示形式以@开头,这就是破坏了您的查询。
  • 由于您的属性值似乎已经嵌入了引用,因此不需要在SQL字符串中引用它们 - 除此之外,'['...']'不是引用字符串文字的正确方法。

因此:

$insertquery="
INSERT INTO [dbo].[TESTTB01]
   (Date,SName,ACPU,MEMU,DRVC)
     VALUES
   ($($ENTRY.QDate), $($ENTRY.ServerName), $($Entry.CPULoad), $($Entry.MemLoad),$($Entry.CDrive))
GO

退一步:考虑听取Larnu的建议来参数化你的查询,而不是将值作为文字嵌入查询字符串中。


0
投票

最终的代码是

$ServerName = "SQLSRV"
$DatabaseName = "Automation"
$conn=New-Object System.Data.SqlClient.SQLConnection
$ConnectionString =  "Server = $SQLServer; Database = $SQLDBName; 
User ID= automationusr; Password= Password@SQL" 
$conn.ConnectionString=$ConnectionString
$conn.Open()
$ServerListFile = "C:\Scripts\ServerList.txt"
$ServerList = Get-Content $ServerListFile -ErrorAction SilentlyContinue  
$Result = @()  
ForEach($computername in $ServerList)  
{ 

$AVGProc = Get-WmiObject -computername $computername win32_processor |  
Measure-Object -property LoadPercentage -Average | Select Average 
$OS = gwmi -Class win32_operatingsystem -computername $computername | 
Select-Object @{Name = "MemoryUsage"; Expression = {“{0:N2}” -f ((($_.TotalVisibleMemorySize - $_.FreePhysicalMemory)*100)/ $_.TotalVisibleMemorySize) }} 
$vol = Get-WmiObject -Class win32_Volume -ComputerName $computername -Filter "DriveLetter = 'C:'" | 
Select-object @{Name = "C PercentFree"; Expression = {“{0:N2}” -f  (($_.FreeSpace / $_.Capacity)*100) } } 
$result += [PSCustomObject] @{  
ServerName = "'$computername'" 
CPULoad = "'$($AVGProc.Average)%'" 
MemLoad = "'$($OS.MemoryUsage)%'" 
CDrive = "'$($vol.'C PercentFree')%'" 
QDate = "'$(Get-Date -Format "yyyyMMdd hh:MM:ss tt")'"
    } 

    Foreach($Entry in $Result)  
{
$QDate=$TESTTB01.Date
$ServerName=$TESTTB01.SName
$CPULoad=$TESTTB01.ACPU
$MemLoad=$TESTTB01.MEMU
$CDrive=$TESTTB01.DRVC

}
$insertquery="
INSERT INTO [dbo].[TESTTB01]
   (Date,SName,ACPU,MEMU,DRVC)
     VALUES
   ($($ENTRY.QDate), $($ENTRY.ServerName), $($Entry.CPULoad), $($Entry.MemLoad),$($Entry.CDrive))
GO
"
Invoke-SQLcmd -ServerInstance 'SQL01' -query $insertquery -U automationusr -P Password@SQL -Database Automation
}
© www.soinside.com 2019 - 2024. All rights reserved.