我不断收到可怕的“在预期条件的上下文中指定的非布尔类型的表达式。”错误出现在粗体“dbo.v_R_System.ResourceID”在下面代码中的“From”语句部分中。我还收到了“关键字‘WHERE’附近的语法不正确。”错误消息。
我的这个查询错误在哪里?
SELECT DISTINCT
dbo.v_GS_COMPUTER_SYSTEM.Name0 AS [Computer Name],
[Top Console User] = CASE
WHEN (dbo.v_GS_SYSTEM_CONSOLE_USAGE_MAXGROUP.TopConsoleUser0 is NULL or dbo.v_GS_SYSTEM_CONSOLE_USAGE_MAXGROUP.TopConsoleUser0 = '-1')
THEN 'Unknown'
ELSE dbo.v_GS_SYSTEM_CONSOLE_USAGE_MAXGROUP.TopConsoleUser0
END,
dbo.v_R_System.AD_Site_Name0 AS [Active Directory Site Name],
dbo.v_R_System.Resource_Domain_OR_Workgr0 AS [Domain Name],
dbo.v_GS_OPERATING_SYSTEM.Caption0 AS [Operating System],
dbo.v_GS_OPERATING_SYSTEM.CSDVersion0 AS [Service Pack],
dbo.v_GS_COMPUTER_SYSTEM.Model0 AS [Computer Model],
dbo.v_GS_OPERATING_SYSTEM.InstallDate0 AS [OS Install Date]
FROM
dbo.v_GS_COMPUTER_SYSTEM INNER JOIN
dbo.v_GS_SYSTEM_CONSOLE_USAGE_MAXGROUP ON dbo.v_GS_COMPUTER_SYSTEM.ResourceID = dbo.v_GS_SYSTEM_CONSOLE_USAGE_MAXGROUP.ResourceID INNER JOIN
dbo.v_GS_OPERATING_SYSTEM INNER JOIN
dbo.v_R_System ON dbo.v_GS_OPERATING_SYSTEM.ResourceID = **dbo.v_R_System.ResourceID**
WHERE
dbo.v_GS_OPERATING_SYSTEM.Caption0 NOT LIKE '%Server%'
GROUP BY
dbo.v_GS_COMPUTER_SYSTEM.Name0,
dbo.v_GS_SYSTEM_CONSOLE_USAGE_MAXGROUP.TopConsoleUser0,
dbo.v_R_System.AD_Site_Name0,
dbo.v_R_System.Resource_Domain_OR_Workgr0,
dbo.v_GS_OPERATING_SYSTEM.CSDVersion0,
dbo.v_GS_PC_BIOS.Manufacturer0,
dbo.v_GS_COMPUTER_SYSTEM.NumberOfProcessors0,
dbo.v_GS_OPERATING_SYSTEM.Caption0,
dbo.v_GS_COMPUTER_SYSTEM.Model0,
dbo.v_GS_OPERATING_SYSTEM.InstallDate0
答案1
最有可能的是,您在优先级问题上遇到了麻烦,并且您的 from 子句没有按照您想象的方式进行评估。
尝试添加括号,如下所示:
FROM
((dbo.v_GS_COMPUTER_SYSTEM
INNER JOIN dbo.v_GS_SYSTEM_CONSOLE_USAGE_MAXGROUP
ON (dbo.v_GS_COMPUTER_SYSTEM.ResourceID =
dbo.v_GS_SYSTEM_CONSOLE_USAGE_MAXGROUP.ResourceID)
)
INNER JOIN dbo.v_GS_OPERATING_SYSTEM
)
INNER JOIN dbo.v_R_System ON (dbo.v_GS_OPERATING_SYSTEM.ResourceID =
dbo.v_R_System.ResourceID)
如果这不是您真正想要的,您就会发现问题了。
值得注意的是,虽然这不是严格必要的并且可能由查询执行计划程序来处理,但是如果您在开始执行连接之前使用子查询来处理 WHERE 子句中的条件,您可能能够创建较小的临时表。
我也不完全确定你的 CASE 语法是否正确。我相信应该是
CASE WHEN
(dbo.v_GS_SYSTEM_CONSOLE_USAGE_MAXGROUP.TopConsoleUser0 is NULL
or dbo.v_GS_SYSTEM_CONSOLE_USAGE_MAXGROUP.TopConsoleUser0 = '-1')
THEN 'Unknown'
ELSE dbo.v_GS_SYSTEM_CONSOLE_USAGE_MAXGROUP.TopConsoleUser0
END AS [Top Console User]
但我已经知道我错了。我预期的错误应该是“未知字段 [Top Console User]”。
答案2
SCCM 报告名称:工作站上的顶级控制台用户/常规计算机信息
解释:
这就是我修复上述错误初始代码的方法,这样我就可以提取有关顶级控制台用户的信息以及一些常规计算机信息,例如制造商和型号。顺便说一句,顶级控制台用户利用 SCCM 资产智能(当启用时)并要求“审计账户登录事件“策略也在您的环境中启用,这可以通过 GPO 完成。您可以在此处阅读有关启用此策略的更多信息微软技术网。此外,我遇到了此报告未显示所有 NULL 值的问题,但后来我尝试了一下我的连接,并意识到我需要一个左连接和两个右连接才能显示我环境中所有工作站的所有数据。因此,下面的报告将做两件事:
- 如果正在审核安全日志以获取成功登录(这也可以通过使用前面提到的 GPO 来完成)或者手动按系统执行,它将显示哪些系统具有顶级控制台用户。
和
- 它还将显示所有 NULL 值(在本例中为“未启用审核帐户登录事件”,因为这是我告诉报告用来替换 NULL 值的),这显然会告诉您哪些系统没有被审核的安全日志。
笔记:
即使您没有通过 GPO 启用“审核帐户登录事件”,某些系统也可能会报告“顶级控制台用户”,但前提是出于某种原因,某人(例如超级用户或本地管理员等)手动将安全日志配置为在该特定系统上进行审核。因此,如果您看到某些系统会报告此信息,但大多数系统不会报告,请不要惊慌,因为这很可能就是原因。
SQL 代码:
选择不同的
dbo.v_GS_COMPUTER_SYSTEM.Name0 AS [Computer Name],
[Top Console User] = CASE WHEN
(dbo.v_GS_SYSTEM_CONSOLE_USAGE.TopConsoleUser0) is NULL
THEN 'Audit Account Logon Events Not Enabled'
ELSE dbo.v_GS_SYSTEM_CONSOLE_USAGE.TopConsoleUser0
END,
dbo.v_R_System.Resource_Domain_OR_Workgr0 AS [Domain Name],
dbo.v_GS_OPERATING_SYSTEM.Caption0 AS [Operating System],
dbo.v_GS_OPERATING_SYSTEM.CSDVersion0 AS [Service Pack],
dbo.v_GS_COMPUTER_SYSTEM.Manufacturer0 AS [Computer Manufacturer],
dbo.v_GS_COMPUTER_SYSTEM.Model0 AS [Computer Model]
从
dbo.v_R_System
Left Join
dbo.v_GS_SYSTEM_CONSOLE_USAGE ON dbo.v_R_System.ResourceID = dbo.v_GS_SYSTEM_CONSOLE_USAGE.ResourceID
Right Join
dbo.v_GS_COMPUTER_SYSTEM ON dbo.v_GS_SYSTEM_CONSOLE_USAGE.ResourceID = dbo.v_GS_COMPUTER_SYSTEM.ResourceID
Right Join
dbo.v_GS_OPERATING_SYSTEM ON dbo.v_GS_COMPUTER_SYSTEM.ResourceID = dbo.v_GS_OPERATING_SYSTEM.ResourceID
在哪里
(Not (dbo.v_GS_OPERATING_SYSTEM.Caption0 Like '%Server%'))
通过...分组
dbo.v_GS_COMPUTER_SYSTEM.Name0,
dbo.v_GS_SYSTEM_CONSOLE_USAGE.TopConsoleUser0,
dbo.v_R_System.Resource_Domain_OR_Workgr0,
dbo.v_GS_OPERATING_SYSTEM.Caption0,
dbo.v_GS_OPERATING_SYSTEM.CSDVersion0,
dbo.v_GS_COMPUTER_SYSTEM.Manufacturer0,
dbo.v_GS_COMPUTER_SYSTEM.Model0
排序依据
[Top Console User]
SCCM 报告名称:上次登录的用户/工作站上的 SCCM 客户端签到
解释:
现在,这是我与资产管理部门交谈后最终需要使用的代码,他们告诉我,他们实际上并不需要顶级控制台用户,而是需要上次登录的用户。他们不明白这两者之间的区别,所以我不得不向他们解释这一点,然后他们说:“哦,我们现在明白了。不,我们需要的是上次登录的用户,以及工作站上次签到或在线的时间,谢谢。”所以,我处理了他们能够使用的这段代码。顺便说一下,这段代码没有利用 SCCM 资产智能,并且不需要启用安全日志审计即可使其工作。此外,为了获取工作站上次“签到”的时间,我只需使用上次硬件清单扫描来提取此信息。还有一件事,要从“dbo.v_GS_COMPUTER_SYSTEM.UserName0”获取真正的上次登录用户,应该每天启用硬件清单扫描,这就是我在 SCCM 环境中配置它的方式,所以我使用它。但是,如果您没有启用硬件清单来每天运行,那么您应该从“V_GS_NETWORK_LOGIN_PROFILE.Name0”获取最后登录的用户数据。
SQL 代码:
选择不同的
dbo.v_GS_COMPUTER_SYSTEM.Name0 AS [Computer Name],
dbo.v_GS_COMPUTER_SYSTEM.Manufacturer0 AS [Computer Manufacturer],
dbo.v_GS_COMPUTER_SYSTEM.Model0 AS [Computer Model],
[Last Logged On User] = CASE WHEN
MAX(dbo.v_GS_COMPUTER_SYSTEM.UserName0) is NULL
THEN 'Uknown'
ELSE dbo.v_GS_COMPUTER_SYSTEM.UserName0
END,
dbo.v_R_SYSTEM.Resource_Domain_OR_Workgr0 AS [Domain],
dbo.v_GS_OPERATING_SYSTEM.Caption0 AS [Operating System],
dbo.v_GS_OPERATING_SYSTEM.CSDVersion0 AS [Service Pack],
dbo.v_GS_WORKSTATION_STATUS.LastHWScan AS [Last SCCM Client Check-In]
从
dbo.v_GS_COMPUTER_SYSTEM
INNER JOIN
dbo.v_R_System ON dbo.v_GS_COMPUTER_SYSTEM.ResourceID = dbo.v_R_System.ResourceID
INNER JOIN
dbo.v_GS_OPERATING_SYSTEM ON dbo.v_R_System.ResourceID = dbo.v_GS_OPERATING_SYSTEM.ResourceID
INNER JOIN
dbo.v_GS_WORKSTATION_STATUS ON dbo.v_GS_OPERATING_SYSTEM.ResourceID = dbo.v_GS_WORKSTATION_STATUS.ResourceID
在哪里
dbo.v_GS_OPERATING_SYSTEM.Caption0 Not Like '%Server%' and dbo.v_R_SYSTEM.Name0 Not Like 'WN%'
通过...分组
dbo.v_GS_COMPUTER_SYSTEM.Name0,
dbo.v_GS_COMPUTER_SYSTEM.Manufacturer0,
dbo.v_GS_COMPUTER_SYSTEM.Model0,
dbo.v_GS_COMPUTER_SYSTEM.UserName0,
dbo.v_R_System.Resource_Domain_OR_Workgr0,
dbo.v_GS_OPERATING_SYSTEM.Caption0,
dbo.v_GS_OPERATING_SYSTEM.CSDVersion0,
dbo.v_GS_WORKSTATION_STATUS.LastHWScan
排序依据
[Computer Name]