Sql Powershell脚本从数据表读取时在值中找到fullstop时出错

Sql Powershell脚本从数据表读取时在值中找到fullstop时出错,sql,powershell,Sql,Powershell,我已经修改了一个Powershell脚本,它从我的庄园中的一系列服务器读取磁盘空间。我遇到的问题是,一些服务器名称有句号“ServerA.A.A”,当Powershell返回值以从该服务器获取数据时,它会说 Invoke Sqlcmd:传递到左侧或右侧的长度参数无效 子串函数。声明已终止 我曾尝试在服务器名称周围添加单引号和双引号,但它的读取方式是“ServerA.A.A,而不是ServerA.A.A” 我如何在服务器名称周围添加单引号或双引号,但让PS读取它而不读取它们 编辑:-我已经在下面添

我已经修改了一个Powershell脚本,它从我的庄园中的一系列服务器读取磁盘空间。我遇到的问题是,一些服务器名称有句号“ServerA.A.A”,当Powershell返回值以从该服务器获取数据时,它会说

Invoke Sqlcmd:传递到左侧或右侧的长度参数无效 子串函数。声明已终止

我曾尝试在服务器名称周围添加单引号和双引号,但它的读取方式是“ServerA.A.A,而不是ServerA.A.A”

我如何在服务器名称周围添加单引号或双引号,但让PS读取它而不读取它们

编辑:-我已经在下面添加了完整的代码,很抱歉没有早点这么做,我已经用过很多次这个来查找q的答案,但是我自己已经很久没有发布了

   $server = "XXX"
$inventoryDB = "XXXX"

#Create the DiskSpace Table if it doesn't exist in your centralized instance 
#You can remove the 'Monitoring' schema if you want.
$diskSpaceTableCreationQuery = "
IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'DiskSpace' AND xtype = 'U')
CREATE TABLE [dbo].[DiskSpace](
   [Instance] [nvarchar](50) NULL,
   [DBName] [nvarchar](255) NULL,
   [PhysicalFileLocation] [nvarchar](500) NULL,
   [Drive] [nvarchar](50) NULL,
   [DBFileSizeMB] [int] NULL,
   [TotalSpaceInMB] [int] NULL,
   [FreeSpaceInMB] [int] NULL,
   [PercentFreeSpace] [float] NULL
) ON [PRIMARY]
"
Invoke-Sqlcmd -Query $diskSpaceTableCreationQuery -Database $inventoryDB -ServerInstance $server

#Clean the DiskSpace table
Invoke-Sqlcmd -Query "TRUNCATE TABLE dbo.DiskSpace" -Database $inventoryDB -ServerInstance $server

#Create the thresholds Table if it doesn't exist in your centralized instance
$thresholdsTableCreationQuery = " 
IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'thresholds' AND xtype = 'U')
CREATE TABLE [dbo].[thresholds](
   [id] [tinyint] IDENTITY(1,1) NOT NULL,
   [item] [varchar](25) NOT NULL,
   [warning_value] [tinyint] NOT NULL,
   [critical_value] [tinyint] NOT NULL,
 CONSTRAINT [PK_thresholds] PRIMARY KEY CLUSTERED 
(
   [id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
"
Invoke-Sqlcmd -Query $thresholdsTableCreationQuery -Database $inventoryDB -ServerInstance $server

#Insert the threshold value to set the upper cap that the SP will use to limit the result set (the value won't be inserted if it already exists.
#This is designed this way so that you can use this table to store threshold values for other purposes (CPU, RAM, etc.)
$thresholdValueInsertQuery = "
IF NOT EXISTS (SELECT item FROM dbo.thresholds 
               WHERE item = 'disk_space')
BEGIN
   INSERT INTO dbo.thresholds VALUES ('disk_space', 50)
END
"
Invoke-Sqlcmd -Query $thresholdvalueInsertQuery -Database $inventoryDB -ServerInstance $server

#Fetch all the instances with the respective SQL Server Version
<#
   This is an example of the result set that your query must return
   ##################################################
   # name                     # instance            #
   ##################################################
   # server1.domain.net,45000 # server1             #
   # server1.domain.net,45001 # server1\MSSQLSERVER1#
   # server2.domain.net,45000 # server2             #
   # server3.domain.net,45000 # server3             #
   # server4.domain.net       # server4\MSSQLSERVER2#
   ################################################## 
#>

#If you don't have such table in your environment, the following block of code will create it for you. You just simply have to make sure to populate it accordingly.
$instancesTableCreationQuery = "
IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'instances' AND xtype = 'U')
CREATE TABLE instances(
   [name] [nvarchar](128) NULL,
   [instance] [nvarchar](128) NULL
) ON [PRIMARY]
"
Invoke-Sqlcmd -Query $instancesTableCreationQuery -Database $inventoryDB -ServerInstance $server

$instanceLookupQuery = "SELECT name, instance FROM instances"

$instances = Invoke-Sqlcmd -ServerInstance $server -Database $inventoryDB -Query $instanceLookupQuery

#For each instance, grab the disk space information
foreach ($instance in $instances){
   $diskSpaceQuery = Invoke-Sqlcmd -ServerInstance $server -Database $inventoryDB -Query "EXEC dbo.disk_space" -MaxCharLength 8000

   #Go grab the disks information for the instance
   Write-Host "Fetching Disk information for instance" $instance.instance
    $results = Invoke-Sqlcmd -Query $diskSpaceQuery.tsql -ServerInstance $instance.name -ErrorAction Stop -querytimeout 30

   #Perform the INSERT in the DiskSpace table only if it returned at least 1 row
   if($results.Length -ne 0){
      #Build the insert statement
      $insert = "INSERT INTO dbo.DiskSpace VALUES"
      foreach($result in $results){
         $insert += "
         (
         '"+$result.Instance+"',
         '"+$result.DBName+"',
         '"+$result.PhysicalFileLocation+"',
         '"+$result.Drive+"',
         "+$result.DBFileSizeMB+",
         "+$result.TotalSpaceInMB+",
         "+$result.FreeSpaceInMB+",
         "+$result.PercentFreeSpace+"
         ),
         "
      }

      #Store the results in the local DiskSpace table in your central instance
      Invoke-Sqlcmd -Query $insert.Substring(0,$insert.LastIndexOf(',')) -ServerInstance $server -Database $inventoryDB
   } 
}
Write-Host "Done!"

我相信您的问题在于上次调用Sqlcmd时PowerShell的变量扩展

PowerShell可能正在做的不是传递$insert.Substring0,$insert.LastIndexOf','的结果,而是传递.Substring0,$insert.LastIndexOf','

虽然我无法测试这一点,但我认为这是您的问题,因为提供了错误消息:

Invoke Sqlcmd:传递给LEFT或SUBSTRING函数的长度参数无效。声明已被终止

这是一个SQL错误,代码中没有使用SQL子字符串函数的地方

要解决此问题,请使用:


$确保表达式的结果是传递给-Query参数的结果。

我认为您的问题在于上次调用Sqlcmd时PowerShell的变量扩展

PowerShell可能正在做的不是传递$insert.Substring0,$insert.LastIndexOf','的结果,而是传递.Substring0,$insert.LastIndexOf','

虽然我无法测试这一点,但我认为这是您的问题,因为提供了错误消息:

Invoke Sqlcmd:传递给LEFT或SUBSTRING函数的长度参数无效。声明已被终止

这是一个SQL错误,代码中没有使用SQL子字符串函数的地方

要解决此问题,请使用:


$确保表达式的结果是传递给-Query参数的结果。

是否有包含双引号的外部单引号对?如果要将服务器名称传递到-ServerInstance参数中,则可以先将服务器名称存储在变量中,然后在其中使用变量:-ServerInstance$servername。对不起,我不知道您的意思。这是我认为是假的代码$instanceLookupQuery=选择名称,instance FROM instances$instances=调用Sqlcmd-ServerInstance$server-Database$inventoryDB-Query$instanceLookupQuery对于每个实例,获取$instances中每个$instance的磁盘空间信息{$diskSpaceQuery=Invoke Sqlcmd-ServerInstance$server-Database$inventoryDB-Query EXEC dbo.disk\u space-MaxCharLength 8000[/code]你能在设置了$server的地方发布代码吗?如果在问题中而不是在注释中发布代码,对每个人来说都会更容易。发布带有任何问题的相关代码非常有帮助。对不起,我已经在原始帖子中添加了完整的代码。你没有包含失败的子字符串或可能在dbo.disk中的左SQL语句_如果有多个结果,$insert将不是有效的SQL。您必须为每组值重复insert到dbo.DiskSpace VALUES字符串中。是否有包含双引号的外部单引号对?如果要将服务器名称传递到-ServerInstance参数中,您可以首先在变量中输入服务器名称,然后在其中使用该变量:-ServerInstance$servername。对不起,我不确定我是否知道您的意思。以下是我认为合适的代码。$instanceLookupQuery=选择名称,instance FROM instances$instances=调用Sqlcmd-ServerInstance$server-数据库$inventoryDB-查询$instanceLookupQu对于每个实例,在$instances{$diskSpaceQuery=Invoke Sqlcmd-ServerInstance$server-Database$inventoryDB-Query EXEC dbo.disk_space-MaxCharLength 8000[/code]中获取每个$instance的磁盘空间信息你能在设置了$server的地方发布代码吗?如果在问题中而不是在注释中发布代码,对每个人来说都会更容易。发布带有任何问题的相关代码非常有帮助。对不起,我已经在原始帖子中添加了完整的代码。你没有包含失败的子字符串或可能在dbo.disk中的左SQL语句_如果有多个结果,$insert将不是有效的SQL。您必须为每一组值重复插入dbo.DiskSpace值字符串。谢谢Mason,现在一切正常,非常感谢
尽管如此,我还是提高了投票率,但这并没有表现出来,因为我没有足够的代表性-谢谢你,梅森,这件事已经开始运作了,非常感谢,我已经对这件事投了更高的票,但它没有表现出来,因为我没有足够的代表-
Invoke-Sqlcmd -Query $($insert.Substring(0,$insert.LastIndexOf(','))) -ServerInstance $server -Database $inventoryDB