VBS - 查找计算机所属的 SCCM 集合 ID、名称和包名称?

VBS - Find SCCM Collection Id's, Names and Package Names a computer is apart of?

目前我有 'excel SQL query' 的主题要求,它执行得很好,没有任何问题。

当前 Excel SQL 查询脚本: 我创建了 SQL 连接到 SCCM 服务器的查询并获取以下详细信息。

Excel 2013/2016->数据->连接->工作簿连接-> Excel SQL Query

连接字符串:

Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=True;Initial Catalog=CM_CAS;Data Source=<SCCMServerIP>;Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Workstation ID=<SCCMServerHostName>;Use Encryption for Data=False;Tag with column collation when possible=False

命令类型: SQL

命令文本:

DECLARE @machname varchar(max)

SET @machname = '<DeviceHostName>'

select CollectionID,CollectionName,packagename,@machname as MachineName from v_AdvertisementInfo 

-- select AssignmentID,AssignmentName,CollectionID,CollectionName,ApplicationName,AppModelID from v_ApplicationAssignment

where CollectionID in 

(select FCM.CollectionId from dbo.v_R_System r join 

dbo.v_FullCollectionMembership FCM on R.ResourceID = FCM.ResourceID join 

dbo.v_Collection C on C.CollectionID = FCM.CollectionID Where R.Name0 

= @machname) and 

ProgramName not like '%Remove%'and 
 ProgramName not like '%Un-Install%'and 
 CollectionName not like '%Test%' and
CollectionName not like '%temp%'


union

select CollectionID,CollectionName,ApplicationName,@machname as MachineName from v_ApplicationAssignment
where CollectionID in 

(select FCM.CollectionId from dbo.v_R_System r join 

dbo.v_FullCollectionMembership FCM on R.ResourceID = FCM.ResourceID join 

dbo.v_Collection C on C.CollectionID = FCM.CollectionID Where R.Name0 

= @machname) and

CollectionName not like '%Test%' and
CollectionName not like '%temp%'

++++++++++++++++++++++++++++++++++++++++++++++

示例 Excel 输出如下

hostname 'IN-00001236'

Result/Output

要求是: 笔记本电脑 EOL 刷新

收集属于 IN-00001236(EOL 设备)成员的所有集合 ID,并将新设备主机名 (IN-1111) 添加到结果集合 ID 中!然后从 SCCM 中删除 IN-00001236。在 excel/CSV?

中生成报告

我有一个挑战在上面 Excel SQL 查询?就像我在 'Command Text'

下每个 time/run 都有 add/replace 主机名

所以,我需要使用 VBS 或 PS 来自动完成这个完整的过程?

如果我对你的理解是正确的,你希望新记录包含旧记录的所有成员ps。

在我看来你可以只关注 collection memberships,部署到 collection 是一个包,应用程序还是更新应该不重要,只要collection相同。

因此,首先您需要将您的设备名称转换为 resourceid,因为它们是所有 sccm 表中的主键:

$WS = 'IN-00001236'
$resourceID = (Get-WmiObject -Class "SMS_R_System" -Filter "(Name = '$WS')" | Select-Object -last 1).ResourceID

一旦你拥有了,你就可以获得所有 collection 成员

$collectionMembers = (Get-WmiObject -Class "SMS_FullCollectionMembership" -Filter "(ResourceID = '$resourceID')"  | where { $_.IsDirect -eq $true }).CollectionID

要删除一条记录使用这个

[void](Get-WmiObject -Class "SMS_R_System" -Filter "(ResourceID = '$resourceID')").Delete()

现在你必须将它们添加到新记录中(首先再次获取 resourceID)

Foreach($CollID in $collectionMembers) {
    $CollectionQuery = Get-WmiObject -Class "SMS_Collection" -Filter "CollectionID = '$CollID'"
    $directRule = (Get-WmiObject -List -Class "SMS_CollectionRuleDirect").CreateInstance()
    $directRule.ResourceClassName = "SMS_R_System"
    $directRule.ResourceID = $newResourceID
    [void]$CollectionQuery.AddMemberShipRule($directRule)
}

如果您想在一个循环中将其用于多个设备,您只需使用 oldrecord,newrecord 创建一个 csv 文件 导入

$records = Import-Csv <path to csv> -Header old,new

然后在所有代码之外使用循环,如

foreach ($record in $records) {
  # inside here use $record.old or $record.new for the old/new names like
  # $WS = $record.old
}

现在我不知道如果你只需要一个脚本来完成工作,你是否甚至还需要 excel 文件,但如果你真的需要,你可以创建一个 excel 可读的文件来自 powershell 的 csv export-csv(可能需要诸如 -Delimiter ';' -NoTypeInformation -Encoding UTF8 之类的选项以便于阅读)

理论上您也可以在 powershell 中执行整个 sql 查询

$sqlText = "your query"
$SQLConnection = new-object System.Data.SqlClient.SQLConnection("Server=<sccmserver>;Database=<sccm db>;Integrated Security=SSPI")
$SQLConnection.Open();

$cmd = new-object System.Data.SqlClient.SqlCommand($sqlText, $SQLConnection);    
$reader = $cmd.ExecuteReader()

while ($reader.Read()) {
    $reader["<columnname>"] 
}

并在 ps 脚本中重新创建您的文件

终于完成了如下的VBS。一切正常。

Dim connect, sql, resultSet, pth, txt

Set ObjFSO = CreateObject("Scripting.FileSystemObject")
Set connect = CreateObject("ADODB.Connection")
connect.ConnectionString = "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=True;Initial Catalog=CM_CAS;Data Source=<SCCMServerIP>;Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Workstation ID=<SCCMServerHostName>;Use Encryption for Data=False;Tag with column collation when possible=False;Trusted_Connection=True;"
connect.Open

sql="select CollectionID,CollectionName,packagename,<HostName> as MachineName from v_AdvertisementInfo where CollectionID in (select FCM.CollectionId from dbo.v_R_System r join dbo.v_FullCollectionMembership FCM on R.ResourceID = FCM.ResourceID join dbo.v_Collection C on C.CollectionID = FCM.CollectionID Where R.Name0 = 'HostName') and ProgramName not like '%Remove%'and ProgramName not like '%Un-Install%'and CollectionName not like '%Test%' and CollectionName not like '%temp%' union select CollectionID,CollectionName,ApplicationName,@machname as MachineName from v_ApplicationAssignment where CollectionID in (select FCM.CollectionId from dbo.v_R_System r join dbo.v_FullCollectionMembership FCM on R.ResourceID = FCM.ResourceID join dbo.v_Collection C on C.CollectionID = FCM.CollectionID Where R.Name0 = 'HostName') and CollectionName not like '%Test%' and CollectionName not like '%temp%'"

Set resultSet = connect.Execute(sql)

pth = "C:\test\test.csv"

Set txt = ObjFSO.CreateTextFile(pth, True)

On Error Resume Next
resultSet.MoveFirst
Do While Not resultSet.eof
  txt.WriteLine(resultSet(0) & "," & resultSet(1) & "," & resultSet(2))
  resultSet.MoveNext
Loop

resultSet.Close
connect.Close
Set connect = Nothing