Sql Powershell脚本从数据表读取时在值中找到fullstop时出错
我已经修改了一个Powershell脚本,它从我的庄园中的一系列服务器读取磁盘空间。我遇到的问题是,一些服务器名称有句号“ServerA.A.A”,当Powershell返回值以从该服务器获取数据时,它会说 Invoke Sqlcmd:传递到左侧或右侧的长度参数无效 子串函数。声明已终止 我曾尝试在服务器名称周围添加单引号和双引号,但它的读取方式是“ServerA.A.A,而不是ServerA.A.A” 我如何在服务器名称周围添加单引号或双引号,但让PS读取它而不读取它们 编辑:-我已经在下面添加了完整的代码,很抱歉没有早点这么做,我已经用过很多次这个来查找q的答案,但是我自己已经很久没有发布了Sql Powershell脚本从数据表读取时在值中找到fullstop时出错,sql,powershell,Sql,Powershell,我已经修改了一个Powershell脚本,它从我的庄园中的一系列服务器读取磁盘空间。我遇到的问题是,一些服务器名称有句号“ServerA.A.A”,当Powershell返回值以从该服务器获取数据时,它会说 Invoke Sqlcmd:传递到左侧或右侧的长度参数无效 子串函数。声明已终止 我曾尝试在服务器名称周围添加单引号和双引号,但它的读取方式是“ServerA.A.A,而不是ServerA.A.A” 我如何在服务器名称周围添加单引号或双引号,但让PS读取它而不读取它们 编辑:-我已经在下面添
$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