USC-SCCM.psm1
<#v1.5
(Modified Send-CfgMachinePolicyUpdate to wait 2 seconds rather than 10 between downloading and evaluating policy) (Modified Send-WOL to send the WOL packet to port 1230 and port 9) (Modified Get-CfgClientInventory default properties) (Added new Install-CCM command) (Added Admin test to Send-Wol) #> #v1.4 (Added documentation) #v1.3 (Added Send-RepairCCM) function Test-CurrentAdminRights { #Return $True if process has admin rights, otherwise $False $user = [System.Security.Principal.WindowsIdentity]::GetCurrent() $Role = [System.Security.Principal.WindowsBuiltinRole]::Administrator return (New-Object Security.Principal.WindowsPrincipal $User).IsInRole($Role) } function Get-CfgCollectionMembers { <# .SYNOPSIS Retreive members of an SCCM collection. .DESCRIPTION Connects to the primary site server and queries the WMI namespace for members of a collection, based on input. .PARAMETER Collection The descriptive name of a collection. If spaces are in the name, surround it by quotes. .EXAMPLE C:\PS>Get-CfgCollectionMembers "VMware vSphere Client 4.1 MSI WKS" ComputerName Collection ------------ ---------- GMNQ12S VMware vSphere Client 4.1 MSI WKS .NOTES Author: Jesse Harris For: University of Sunshine Coast Date Created: 09 Jan 2012 ChangeLog: 1.0 - First Release #> Param( [Parameter(Mandatory = $True, HelpMessage = "Please enter a collection name", ValueFromPipeLine = $true, ValueFromPipelinebyPropertyName = $True)] [ValidateNotNullOrEmpty()] [String[]] $Collection,$Site="SC1", $SiteServer="wsp-configmgr01.usc.internal", $Property ) $Collections = Get-WmiObject -ComputerName $SiteServer -Namespace "root\sms\site_$($site)" -Query ` "Select * from SMS_Collection Where Name like '$Collection'" ForEach ( $Col in $Collections ) { $Members = Get-WmiObject -ComputerName $SiteServer -Namespace "root\sms\site_$($site)" -Query ` "Select * from $($Col.MemberClassName)" #"$($Col.Name)" If ($Property) { $Members | Select-Object $Property } Else { $Members | Select-Object @{label='ComputerName';expression={$_.Name}},@{label='Collection';expression={$Col.Name}} } } } function Get-CfgClientInventory { <# .SYNOPSIS Retreive Inventory information of a Config Manager Client. .DESCRIPTION Connects to the primary site server and queries the WMI namespace for client inventory. .PARAMETER ComputerName The name of a ConfigMgr client, registered with the Site Server. The percent symbol can be used inplace as a wildcard. .PARAMETER UserName If the UserName parameter is used, a search will be performed for ConfigMgr clients where the username matches LastLogonUserName. The percent symbol can be used inplace as a wildcard. .PARAMETER Properties Use the Properties parameter to specify additonal properties to load. These properties have additional network/load cost as they create additional WMI queries. Available properties are: VLAN, Monitor(Returns MonitorCount and MonitorRes), DockStatus, Memory, Model Manufacturer, BuildInfo, Properties. .EXAMPLE C:\PS>Get-CfgClientInventory 6WMPSN1 ComputerName LastLogonUserName IPAddresses ------------ ----------------- ---------- 6WMPSN1 jpharris {169.254.71.251, 172.16.70... .EXAMPLE C:\PS>Get-CfgClientInventory -UserName jpha% ComputerName LastLogonUserName IPAddresses ------------ ----------------- ---------- 6WMPSN1 jpharris {169.254.71.251, 172.16.70... VDI-WIN7X86-016 jpharris {10.0.2.19, fe80::ed59:db1... .EXAMPLE C:\PS>Get-CfgClientInventory 6WMPSN1 -Properties VLAN,Model,Monitor,DockStatus Returns additional properties of system 6wmpsn1 .EXAMPLE C:\PS>Get-CfgClientInventory 6WMPSN1 -Property Name,IPAddresses,MACAddresses Name IPAddresses Macaddresses ---- ----------- ------------ 6WMPSN1 203.57.189.58 00:50:56:C0:00:01 .EXAMPLE C:\PS>Get-CfgCollectionMembers -Collection "Lab DG40" | Get-CfgClientInventory -Properties BuildInfo Returns Build times and management point for the collection members of Lab DG40 .EXAMPLE C:\PS>Get-CfgClientInventory 6WMPSN1 | Select -ExpandProperty IPAddresses 169.254.71.251 172.16.70.159 192.168.201.1 203.57.189.153 fe80::954a:bf66:6607:4206 fe80::b1af:461b:efa:176 fe80::b83a:7f75:cfcc:47fb fe80::fda2:bc20:ea38:6c80 .NOTES Author: Jesse Harris For: University of Sunshine Coast Date Created: 09 Jan 2012 ChangeLog: 1.0 - First Release 1.1 - 10/04/2012 - Modified default properties and docs #> [CmdletBinding()] Param( [Parameter(ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] [string[]]$ComputerName="$env:computername",$UserName, $Site="SC1", $SiteServer="wsp-configmgr01.usc.internal",$Properties,[Switch]$ExtendedData) PROCESS { function CfgClientInventory-Worker { Param($Name,$User) #Set Default Object properties $defaultProperties = @('ComputerName','LastLogonUserName', 'IPAddresses') If ($Name -ne $null) { $Query = "Select * from SMS_R_System Where Name like '$Name'" } ElseIf ($UserName -ne $null) { $Query = "Select * from SMS_R_System Where LastLogonUserName like '$User'" } $QueryResults = Get-WmiObject -ComputerName $SiteServer -Namespace "root\sms\site_$($Site)" ` -Query $Query Foreach ($Result in $QueryResults) { $MonitorRes = $null $MonitorCount = $null $Result | Add-Member -MemberType NoteProperty -Name ComputerName -Value $Result.Name Switch ($Properties) { <#VLAN { $VLANQuery = 'Select Ranges from SMS_G_System_USC_MOEVLAN Where ResourceID = "' + $Result.ResourceID + '"' $Result | Add-Member -MemberType NoteProperty -Name VLAN -Value (Get-WMIObject -ComputerName $SiteServer -Namespace "root\sms\site_$($Site)" -Query $VLANQuery).Ranges $defaultProperties += "VLAN" }#> Model { $ModelQuery = 'Select Model from SMS_G_System_COMPUTER_SYSTEM Where ResourceID = "' + $Result.ResourceID + '"' $Result | Add-Member -MemberType NoteProperty -Name Model -Value (Get-WMIObject -ComputerName $SiteServer -Namespace "root\sms\site_$($Site)" -Query $ModelQuery).Model $defaultProperties += "Model" } Monitor { $MonitorQuery = 'Select * from SMS_G_System_DESKTOP_MONITOR Where ResourceID = "' + $Result.ResourceID + '"' $MonitorData = (Get-WMIObject -ComputerName $SiteServer -Namespace "root\sms\site_$($Site)" -Query $MonitorQuery) $MonitorData | Where-Object {$_.ScreenWidth -ne $null} | ForEach-Object {$MonitorRes += "$($_.ScreenWidth)x$($_.ScreenHeight)," $MonitorCount ++} $MonitorRes = $MonitorRes -replace ",$","" $Result | Add-Member -MemberType NoteProperty -Name MonitorCount -Value $MonitorCount $Result | Add-Member -MemberType NoteProperty -Name MonitorRes -Value $MonitorRes $defaultProperties += "MonitorCount","MonitorRes" } Memory { $MemoryQuery = 'Select TotalPhysicalMemory from SMS_G_System_X86_PC_MEMORY Where ResourceID = "' + $Result.ResourceID + '"' $Number = (Get-WMIObject -ComputerName $SiteServer -Namespace "root\sms\site_$($Site)" -Query $MemoryQuery).TotalPhysicalMemory /1kb $Memory = "{0:N0}" -f $Number + " MB" $Result | Add-Member -MemberType NoteProperty -Name Memory -Value $Memory $defaultProperties += "Memory" } <#DockStatus { $DockQuery = 'Select DockingState from SMS_G_System_USC_DOCKINFO Where ResourceID = "' + $Result.ResourceID + '"' $DockStatus = Switch ((Get-WMIObject -ComputerName $SiteServer -Namespace "root\sms\site_$($Site)" -Query $DockQuery).DockingState) { 0 {"Unsupported"} 1 {"UnDocked"} 2 {"Docked"} 3 {"UnKnown"} } $Result | Add-Member -MemberType NoteProperty -Name DockStatus -Value $DockStatus $defaultProperties += "DockStatus" }#> VideoCard { $VCardQuery = 'Select Description,DriverVersion from SMS_G_System_VIDEO_CONTROLLER Where ResourceID = "' + $Result.ResourceID + '"' $VCard = (Get-WMIObject -ComputerName $SiteServer -Namespace "root\sms\site_$($Site)" -Query $VCardQuery) $Result | Add-Member -MemberType NoteProperty -Name VideoCard -Value $VCard.Description $Result | Add-Member -MemberType NoteProperty -Name DriverVersion -Value $VCard.DriverVersion $defaultProperties += "VideoCard","DriverVersion" } Manufacturer { $ManufacturerQuery = 'Select Manufacturer from SMS_G_System_COMPUTER_SYSTEM Where ResourceID = "' + $Result.ResourceID + '"' $Result | Add-Member -MemberType NoteProperty -Name Manufacturer -Value (Get-WMIObject -ComputerName $SiteServer -Namespace "root\sms\site_$($Site)" -Query $ManufacturerQuery).Manufacturer $defaultProperties += "Manufacturer" } BuildInfo { $BuildInfoQuery = 'Select * from SMS_G_System_MOETATTOO Where ResourceID = "' + $Result.ResourceID + '"' $BuildInfo = (Get-WMIObject -ComputerName $SiteServer -Namespace "root\sms\site_$($Site)" -Query $BuildInfoQuery) ForEach ($Build in $BuildInfo) { If ($Build.BuildTimestamp -ne $null) { $Result | Add-Member -MemberType NoteProperty -Name BuildTimestamp -Value ([datetime]::ParseExact([string]$Build.BuildTimestamp,"yyyyMMddHHmmss.000000+600",$null)) $Result | Add-Member -MemberType NoteProperty -Name BuildManagementPoint -Value $Build.BuildManagementPoint $Result | Add-Member -MemberType NoteProperty -Name BuildTSName -Value $Build.BuildTSName $Result | Add-Member -MemberType NoteProperty -Name CoreImageTimestamp -Value ([datetime]::ParseExact([string]$Build.CoreImageTimestamp,"yyyyMMddHHmmss.000000+600",$null)) $Result | Add-Member -MemberType NoteProperty -Name CoreImageTSName -Value $Build.CoreImageTSName $defaultProperties = @('ComputerName','BuildTimestamp','BuildTSName') } } } } $defaultDisplayPropertySet = New-Object System.Management.Automation.PSPropertySet('DefaultDisplayPropertySet',[string[]]$defaultProperties) $PSStandardMembers = [System.Management.Automation.PSMemberInfo[]]@($defaultDisplayPropertySet) $Result | Add-Member MemberSet PSStandardMembers $PSStandardMembers -PassThru } } If ($UserName -ne $null) { CfgClientInventory-Worker -User $UserName } Else { If ($PSBoundParameters.ContainsKey('ComputerName')) { Foreach ($Computer in $ComputerName) { CfgClientInventory-Worker -Name $Computer } } Else { CfgClientInventory-Worker -Name $ComputerName } } } } function Test-CfgCollectionMembers { <# .SYNOPSIS Performs Test-Connection on the members of the specified collection. .DESCRIPTION Connects to the primary site server and queries the WMI namespace for members of a collection, then reports on their network connectivity. .PARAMETER Collection The descriptive name of a collection. If spaces are in the name, surround it by quotes. .EXAMPLE C:\PS>Test-CfgCollectionMembers 87VZ72S is unavailable F7VZ72S is up 67VZ72S is unavailable 57VZ72S is up B7VZ72S is unavailable G7VZ72S is unavailable 47VZ72S is unavailable 28VZ72S is unavailable J7VZ72S is unavailable .NOTES Author: Jesse Harris For: University of Sunshine Coast Date Created: 09 Jan 2012 ChangeLog: 1.0 - First Release #> Param($Collection, $Site="SC1", $SiteServer="wsp-configmgr01.usc.internal",$TTL=2) Get-CfgCollectionMembers -Collection $Collection -Site $Site -SiteServer $SiteServer | ` ForEach-Object { $TestConn = Test-Connection -TimeToLive $TTL -ComputerName $_.ComputerName -Count 1 -ErrorAction SilentlyContinue If ( $TestConn ) { $_ | Add-Member -MemberType NoteProperty -Name "Online" -Value $True Try { $UserName = (Get-WmiObject -ComputerName $_.ComputerName -Class Win32_computersystem).UserName } Catch { $UserName = $False } If ($UserName.Count -gt 0 -and ($UserName.StartsWith('USC\'))) {$UserName = $UserName.TrimStart('USC\')} $_ | Add-Member -MemberType NoteProperty -Name "CurrentUser" -Value $UserName } Else { $_ | Add-Member -MemberType NoteProperty -Name "Online" -Value $False $_ | Add-Member -MemberType NoteProperty -Name "CurrentUser" -Value $False } $_ } } function Send-CfgUserUpdateTrigger { Param($ComputerName) $sid = ( get-wmiobject -ComputerName $ComputerName -query "SELECT UserSID FROM CCM_UserLogonEvents WHERE LogoffTime = NULL" -namespace "ROOT\ccm").UserSID.replace('-','_'); $sched=([wmi]"\\$ComputerName\root\ccm\Policy\$sid\ActualConfig:CCM_Scheduler_ScheduledMessage.ScheduledMessageID='{00000000-0000-0000-0000-000000000026}'"); $sched.Triggers=@('SimpleInterval;Minutes=1;MaxRandomDelayMinutes=0'); $sched.Put() } function Get-CfgCacheSize { Param($ComputerName=$env:ComputerName) $Cache = ([WMI]"\\$ComputerName\Root\ccm\SoftmgmtAgent:CacheConfig.ConfigKey='Cache'").Size $Cache } function Set-CfgCacheSize { [CmdletBinding()] Param($ComputerName=$env:ComputerName,$Size=25000,[Switch]$Percentage) If ($Percentage) { #Check if size is written in percent If ($Size -gt 99) { Write-Error "Size is not a percentage. Please specify size as a percentage when using the percentage parameter" return } #Okay, lets work out what the size will be if it is a percentage of the current disk. # 1. Get disk info $DiskInfo = Get-WmiObject -ComputerName $ComputerName -Class Win32_LogicalDisk | Where-Object {$_.DeviceID -eq 'C:'} # 2. Get the freespace of C: $Freespace =$DiskInfo.FreeSpace # 3. Get the full size of the disk $DiskSize = $DiskInfo.Size # 4. Work out the percentage of total size $PercentOfTotal = $DiskSize/100*$Size # 5. Do we have this amount available in freespace whilst retaining 10 gig for the OS If (($Freespace - $PercentOfTotal) -gt 10240) { #Yes we will be able to do this $FreeSpaceHR = "{0:#00}Gb" -f ($Freespace /1gb) $PercentOfTotalHR = "{0:#00}Gb" -f ($PercentOfTotal /1gb) Write-Verbose "Freespace is $FreeSpaceHR" Write-Verbose "We will consume $PercentOfTotalHR" #Convert Bytes to Megabytes $SizeinMB = $PercentOfTotal/1024/1024 $Size = [int]$SizeinMB } Else { #No, not enough space available Write-Error "Not enough space available to consume $Size % of disk" return } } $a=([wmi]"\\$ComputerName\ROOT\ccm\SoftMgmtAgent:CacheConfig.ConfigKey='Cache'") $a.Size=$Size $a.Put() If ($? -eq $true) { Write-Verbose "Succesfully set cache size to $Size Mb" } } function Send-CfgAppEval { <# .SYNOPSIS Performs a Application Deployment evaluation cycle on the specified ConfigMgr client. .DESCRIPTION Connect to the WMI namespace of the specified machine and executes a method to trigger the schedule .PARAMETER ComputerName The name of a ConfigMgr client, registered with the Site Server. .EXAMPLE C:\PS>Send-CfgAppEval -ComputerName 9k9562s Executing AppEval for 9k9562s .EXAMPLE Get-CfgCollectionMembers -Collection "Lab DG40" | Send-CfgAppEval Attempts to send an application deployment cycle to members of the collection "Lab DG40" .NOTES Author: Jesse Harris For: University of Sunshine Coast Date Created: 09 Jan 2012 ChangeLog: 1.0 - First Release #> [CmdletBinding()] Param( [Parameter(Mandatory=$true,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] [string[]]$ComputerName) PROCESS { function SendMachineUpdate-Worker { Param($sName) $SCCMClient = [WMIClass]"\\$sName\Root\CCM:SMS_Client" Write-Host "Executing AppEval for $sName" Try {$SCCMClient.psbase.InvokeMethod("TriggerSchedule", "{00000000-0000-0000-0000-000000000121}") } Catch { "An Error occured" } } If ($PSBoundParameters.ContainsKey('ComputerName')) { ForEach ($Computer in $ComputerName) { SendMachineUpdate-Worker -sName $Computer } } Else { SendMachineUpdate-Worker -sName $ComputerName } } } function Send-CfgTrigger { <# .SYNOPSIS Performs a machine policy update on the specified ConfigMgr client. .DESCRIPTION Connect to the WMI namespace of the specified machine and executes a method to download and evaluate machine policy .PARAMETER ComputerName The name of a ConfigMgr client, registered with the Site Server. .EXAMPLE C:\PS>Send-CfgSCEPTrigger -ComputerName 9k9562s Downloading Policy for 9k9562s Evaluating Policy for 9k9562s .EXAMPLE Get-CfgCollectionMembers -Collection "Lab DG40" | Send-Send-CfgSCEPTrigger Attempts to send a machine policy update evaluation to members of the collection "Lab DG40" .NOTES Author: Jesse Harris For: University of Sunshine Coast Date Created: 09 Jan 2012 ChangeLog: 1.0 - First Release #> [CmdletBinding()] Param( [Parameter(Mandatory=$true,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] [string[]]$ComputerName, [string[]]$TriggerName) BEGIN { $Triggers = Switch ($TriggerName) { Machine {'{00000000-0000-0000-0000-000000000021}','{00000000-0000-0000-0000-000000000022}'} User {'{00000000-0000-0000-0000-000000000026}','{00000000-0000-0000-0000-000000000027}' } HWInventory {'{00000000-0000-0000-0000-000000000001}'} SWInventory {'{00000000-0000-0000-0000-000000000002}'} SCEP {'{00000000-0000-0000-0000-000000000221}'} Default {'{00000000-0000-0000-0000-000000000021}','{00000000-0000-0000-0000-000000000022}'} } } PROCESS { function SendMachineUpdate-Worker { Param($sName,$Trigger) $SCCMClient = [WMIClass]"\\$sName\Root\CCM:SMS_Client" Write-Host "Executing trigger $Trigger on $sName" Try {$SCCMClient.psbase.InvokeMethod("TriggerSchedule", $Trigger) } Catch { "An Error occured" } Start-Sleep -Seconds 1 } If ($PSBoundParameters.ContainsKey('ComputerName')) { ForEach ($Computer in $ComputerName) { $Triggers | ForEach-Object { SendMachineUpdate-Worker -sName $Computer -Trigger $_ } } } Else { $Triggers | ForEach-Object { SendMachineUpdate-Worker -sName $ComputerName -Trigger $_ } } } } function Send-CfgSCEPTrigger { <# .SYNOPSIS Performs a machine policy update on the specified ConfigMgr client. .DESCRIPTION Connect to the WMI namespace of the specified machine and executes a method to download and evaluate machine policy .PARAMETER ComputerName The name of a ConfigMgr client, registered with the Site Server. .EXAMPLE C:\PS>Send-CfgSCEPTrigger -ComputerName 9k9562s Downloading Policy for 9k9562s Evaluating Policy for 9k9562s .EXAMPLE Get-CfgCollectionMembers -Collection "Lab DG40" | Send-Send-CfgSCEPTrigger Attempts to send a machine policy update evaluation to members of the collection "Lab DG40" .NOTES Author: Jesse Harris For: University of Sunshine Coast Date Created: 09 Jan 2012 ChangeLog: 1.0 - First Release #> [CmdletBinding()] Param( [Parameter(Mandatory=$true,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] [string[]]$ComputerName) PROCESS { function SendMachineUpdate-Worker { Param($sName) $SCCMClient = [WMIClass]"\\$sName\Root\CCM:SMS_Client" Write-Host "Downloading Policy for $sName" Try {$SCCMClient.psbase.InvokeMethod("TriggerSchedule", "{00000000-0000-0000-0000-000000000221}") } Catch { "An Error occured" } } If ($PSBoundParameters.ContainsKey('ComputerName')) { ForEach ($Computer in $ComputerName) { SendMachineUpdate-Worker -sName $Computer } } Else { SendMachineUpdate-Worker -sName $ComputerName } } } function Send-CfgMachineUpdateTrigger { <# .SYNOPSIS Performs a machine policy update on the specified ConfigMgr client. .DESCRIPTION Connect to the WMI namespace of the specified machine and executes a method to download and evaluate machine policy .PARAMETER ComputerName The name of a ConfigMgr client, registered with the Site Server. .EXAMPLE C:\PS>Send-CfgMachineUpdateTrigger -ComputerName 9k9562s Downloading Policy for 9k9562s Evaluating Policy for 9k9562s .EXAMPLE Get-CfgCollectionMembers -Collection "Lab DG40" | Send-CfgMachineUpdateTrigger Attempts to send a machine policy update evaluation to members of the collection "Lab DG40" .NOTES Author: Jesse Harris For: University of Sunshine Coast Date Created: 09 Jan 2012 ChangeLog: 1.0 - First Release #> [CmdletBinding()] Param( [Parameter(Mandatory=$true,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] [string[]]$ComputerName) PROCESS { function SendMachineUpdate-Worker { Param($sName) $SCCMClient = [WMIClass]"\\$sName\Root\CCM:SMS_Client" Write-Host "Downloading Policy for $sName" Try {$SCCMClient.psbase.InvokeMethod("TriggerSchedule", "{00000000-0000-0000-0000-000000000021}") } Catch { "An Error occured" } Start-Sleep -Seconds 2 Write-Host "Evaluating Policy for $sName" Try {$SCCMClient.psbase.InvokeMethod("TriggerSchedule", "{00000000-0000-0000-0000-000000000022}") } Catch { "An Error occured" } } If ($PSBoundParameters.ContainsKey('ComputerName')) { ForEach ($Computer in $ComputerName) { SendMachineUpdate-Worker -sName $Computer } } Else { SendMachineUpdate-Worker -sName $ComputerName } } } function Send-CfgInventoryUpdateTrigger { <# .SYNOPSIS Performs a hardware inventory on the specified ConfigMgr client. .DESCRIPTION Connect to the WMI namespace of the specified machine and executes a method to execute hardware inventory .PARAMETER ComputerName The name of a ConfigMgr client, registered with the Site Server. .PARAMETER Full Forces a full inventory report rather than a delta. This is achived by deleting the previous inventory which causes a version mismatch. .EXAMPLE C:\PS>Send-CfgInventoryUpdateTrigger -ComputerName 9k9562s .EXAMPLE Get-CfgCollectionMembers -Collection "Lab DG40" | Send-CfgInventoryUpdateTrigger Attempts to send a WMI method to execute hardware inventory update to members of the collection "Lab DG40" .NOTES Author: Jesse Harris For: University of Sunshine Coast Date Created: 09 Jan 2012 ChangeLog: 1.0 - First Release #> Param($ComputerName,[switch]$Full) If ($Full) { $invVersion = Get-WmiObject -ComputerName $ComputerName -Namespace Root\ccm\invagt -Class InventoryActionStatus | Where-Object {$_.InventoryActionID -eq "{00000000-0000-0000-0000-000000000001}"} $invVersion.Delete() } If ( ($ComputerName) ) { $SCCMClient = [WMIClass]"\\$ComputerName\Root\CCM:SMS_Client" } Else { $SCCMClient = [WMIClass]"Root\CCM:SMS_Client" } $SCCMClient.TriggerSchedule("{00000000-0000-0000-0000-000000000001}") } function Get-CfgClientProvisioningMode { (Get-ItemProperty "HKLM:\Software\Microsoft\CCM\CCMExec" -Name "ProvisioningMode").ProvisioningMode } function Set-CfgClientProvisioningMode { Set-ItemProperty "HKLM:\Software\Microsoft\CCM\CCMExec" -Name "ProvisioningMode" -Value "False" -Force Set-ItemProperty "HKLM:\Software\Microsoft\CCM\CCMExec" -Name "SystemTaskExcludes" -Value "" -Force Remove-ItemProperty -Path "HKLM:\Software\Microsoft\SMS\Task Sequence" -Name Package -ea SilentlyContinue Remove-ItemProperty -Path "HKLM:\Software\Microsoft\SMS\Task Sequence" -Name "Active Request Handle" -ea SilentlyContinue Remove-ItemProperty -Path "HKLM:\Software\Microsoft\SMS\Task Sequence" -Name CleanUpFolder -ea SilentlyContinue Remove-ItemProperty -Path "HKLM:\Software\Microsoft\SMS\Task Sequence" -Name Program -ErrorAction SilentlyContinue } function Get-MachineVariables { [CmdletBinding()] Param( [Parameter(ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] [string[]]$ComputerName="$env:computername", $Site="SC1", $SiteServer="wsp-configmgr01.usc.internal",$Property) PROCESS { function CfgClientInventory-Worker { Param($Name) $QueryResults = Get-WmiObject -ComputerName $SiteServer -Namespace "root\sms\site_$($Site)" ` -Query "Select * from SMS_R_System Where Name = '$Name'" If ($Property) { $QueryResults | Select-Object $Property } Else { $QueryResults | Select-Object @{label='ComputerName';expression={$_.Name}},ResourceDomainORWorkgroup,LastLogonUserName,ResourceID } } If ($PSBoundParameters.ContainsKey('ComputerName')) { Foreach ($Computer in $ComputerName) { CfgClientInventory-Worker -Name $Computer } } Else { CfgClientInventory-Worker -Name $ComputerName } } } function Get-MachineVariables { [CmdletBinding()] Param( [Parameter(ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] [string[]]$ComputerName="$env:computername", $Site="SC1", $SiteServer="wsp-configmgr01.usc.internal") PROCESS { function MachineVariables-Worker { Param($Name) If ( $Name -ne "" ) { } Else { $MachineSettings = Get-WmiObject -ComputerName $SiteServer -Namespace "root\sms\site_$($Site)" ` -Query "Select * from SMS_MachineSettings" ForEach ( $Setting in $MachineSettings ) { $ResourceName = ([WMI]"\\$SiteServer\root\sms\site_$($Site):SMS_R_System.ResourceID=$($Setting.ResourceID)").Name $MachineVariables = ([WMI]"$($Setting.__Path)").MachineVariables $MachineVariables | Select-Object @{name='ComputerName';expression={"$ResourceName"}},@{label='VarName';expression={$_.Name}},Value } } } If ($PSBoundParameters.ContainsKey('ComputerName')) { Foreach ($Computer in $ComputerName) { MachineVariables-Worker -Name $Computer } } Else { MachineVariables-Worker -Name $ComputerName } } } function Invoke-WolServer { Param($ComputerName) } function Send-WOL { <# .SYNOPSIS Sends a WOL magic packet to wake a ConfigMgr client. .DESCRIPTION Connect to the WMI namespace of the site server, retreives the MAC addresses of a specified ConfigMgr client and generates WOL packets for each of those MAC addresses. .PARAMETER ComputerName The name of a ConfigMgr client, registered with the Site Server. .EXAMPLE C:\PS>Send-WOL -ComputerName 6wmpsn1 Wake-On-Lan magic packet of length 102 sent to 00:50:56:C0:00:01 Wake-On-Lan magic packet of length 102 sent to 00:50:56:C0:00:08 Wake-On-Lan magic packet of length 102 sent to 1C:65:9D:98:8E:84 Wake-On-Lan magic packet of length 102 sent to F0:4D:A2:59:80:4F .EXAMPLE Get-CfgCollectionMembers -Collection "Lab DG40" | Send-WOL Sends a WOL magic packet for MAC addresses of members of collection Lab DG40 .NOTES Author: Jesse Harris For: University of Sunshine Coast Date Created: 09 Jan 2012 ChangeLog: 1.0 - First Release 1.1 - 10/04/2012 - Tests admin rights to bind on privlidged ports and sends wol on port 1230 and port 9 #> param( [CmdletBinding()] [Parameter(ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] [string[]]$ComputerName="$env:computername", [switch]$Force, [string]$Email, [switch]$Unicast, $SendFrom, $Ports=9, $Site="SC1", $SiteServer="wsp-configmgr01.usc.internal",$MacAddress) PROCESS { If (! (Test-CurrentAdminRights) ) { Write-Host -ForegroundColor Red "Please run as Admin"; return } function Send-WolWorker { Param($Name,$Port,$MacAddress,$From) If (!$MacAddress) { $MachineResults = Get-WmiObject -ComputerName $SiteServer -Namespace Root\SMS\Site_$site ` -Query "Select MACAddresses from SMS_R_System Where SMS_R_System.Name = '$Name' AND SMS_R_System.Active = '1'" If ( $MachineResults -eq $null ) { "No machine results returned"; return 0 } Foreach ($MacAddresses in $MachineResults) { If ( $MacAddresses.MacAddresses -eq $null ) { "No Mac addresses found for $Name"; return 0 } Foreach ($MacAddress in $MacAddresses.MacAddresses) { $mac = $MacAddress.split(':') | %{ [byte]('0x' + $_) } $ScriptBlock = {Param($Port,$mac) $UDPclient = new-Object System.Net.Sockets.UdpClient $UDPclient.Connect(([System.Net.IPAddress]::Broadcast),$Port) $packet = [byte[]](,0xFF * 6) $packet += $mac * 16 [void] $UDPclient.Send($packet, $packet.Length) } If ($From -ne $null) { Invoke-command -ComputerName $From -ScriptBlock $ScriptBlock -ArgumentList $Port,$mac Write-Verbose "Wake-On-Lan magic packet of length $($packet.Length) sent to port $Port on $MacAddress from $From`n" } else { Invoke-Command $ScriptBlock -ArgumentList $Port,$mac Write-Verbose "Wake-On-Lan magic packet of length $($packet.Length) sent to port $Port on $MacAddress from localhost`n" } } } } } function Send-FromTest { Param($SendFrom) If ($SendFrom -and (Test-Connection -ComputerName $SendFrom -Count 1 -Quiet)) { $WinRM = Get-Service -ComputerName $SendFrom -Name WinRM If ($WinRM.Status -eq 'Stopped') { $WinRM.Start() } If (-Not (Test-WSMan -ComputerName $SendFrom -ErrorAction SilentlyContinue)) { Write-Error "WinRM not available, falling back to local wol" return $null } Else { Return $SendFrom } } } If ($SendFrom) { $WinRMHost = Send-FromTest -SendFrom $SendFrom } If ($PSBoundParameters.ContainsKey('ComputerName')) { Foreach ($Computer in $ComputerName) { ForEach ($Port in $Ports) { If ($Unicast) { #Get the IP Address/Subnet of a machine $IPOctets = ([System.Net.DNS]::GetHostByName($Computer)).AddressList.IPAddressToString.Split('.') $IPAddress = "$($IPOctets[0]).$($IPOctets[1]).$($IPOctets[2]).%" #Lets get a list of IP's on the same subnet that are awake $MachinesOnSameIP = Get-WmiObject -ComputerName $SiteServer -Namespace root\sms\site_$Site -Query "Select Name from SMS_R_SYSTEM Where IPADDRESSES Like ""$($IPAddress)""" $WorkingMachine = $null $MachineIndex = 0 While ($WorkingMachine -eq $null -and $MachineIndex -lt $MachinesOnSameIP.Count) { #ForEach ($Machine in $MachinesOnSameIP) { Write-Verbose "Testing $($MachinesOnSameIP[$MachineIndex].Name)" $WorkingMachine = Send-FromTest -SendFrom $MachinesOnSameIP[$MachineIndex].Name $MachineIndex++ } If ($WorkingMachine) { Send-WolWorker -Name $Computer -Port $Port -From $WorkingMachine } Else { #no machines HAHAHAA Write-Verbose -Message "No Machines were found. soz" } } ElseIf ($Force) { $WriteFile = New-Item -Path \\wsp-configmgr01\WOL -Name "$($Computer).wol" -Value $Email -ItemType File -Force Write-Verbose -Message "Machine file written to wsp-configmgr01" } Else { Send-WolWorker -Name $Computer -Port $Port -From $WinRMHost } } } } Else { If ($MacAddress) { ForEach ($Port in $Ports) { Send-WolWorker -MacAddress $MacAddress -Port $Port -From $WinRMHost } } Else { ForEach ($Port in $Ports) { If ($Unicast) { #Get the IP Address/Subnet of a machine $IPOctets = ([System.Net.DNS]::GetHostByName($ComputerName)).AddressList.IPAddressToString.Split('.') $IPAddress = "$($IPOctets[0]).$($IPOctets[1]).$($IPOctets[2]).%" #Lets get a list of IP's on the same subnet that are awake $MachinesOnSameIP = Get-WmiObject -ComputerName $SiteServer -Namespace root\sms\site_$Site -Query "Select Name from SMS_R_SYSTEM Where IPADDRESSES Like ""$($IPAddress)""" $WorkingMachine = $null $MachineIndex = 0 While ($WorkingMachine -eq $null -and $MachineIndex -lt $MachinesOnSameIP.Count) { #ForEach ($Machine in $MachinesOnSameIP) { Write-Verbose "Testing $($MachinesOnSameIP[$MachineIndex].Name)" $WorkingMachine = Send-FromTest -SendFrom $MachinesOnSameIP[$MachineIndex].Name $MachineIndex++ } If ($WorkingMachine) { Send-WolWorker -Name $ComputerName -Port $Port -From $WorkingMachine } Else { #no machines HAHAHAA Write-Verbose -Message "No Machines were found. soz" } } ElseIf ($Force) { $WriteFile = New-Item -Path \\wsp-configmgr01\WOL -Name "$($ComputerName).wol" -Value $Email -ItemType File -Force Write-Verbose -Message "Machine file written to wsp-configmgr01" } Else { Send-WolWorker -Name $ComputerName -Port $Port -From $WinRMHost } } } } } } function Get-CfgIPAddress { <# .SYNOPSIS Uses Get-CfgClientInventory to quickly return IP addresses for a specific computer. .DESCRIPTION A shortcut to 'Get-CfgClientInventory -ComputerName xxxxxxx -Property IPAddresses | Select-Object -Property IPAddresses .PARAMETER ComputerName The name of a ConfigMgr client, registered with the Site Server. .EXAMPLE C:\PS>Get-CfgIPAddress 6WMPSN1 169.254.71.251 172.16.7.30 192.168.201.1 203.57.189.153 fe80::954a:bf66:6607:4206 fe80::b1af:461b:efa:176 fe80::b83a:7f75:cfcc:47fb fe80::fda2:bc20:ea38:6c80 .EXAMPLE Get-CfgCollectionMembers -Collection "Lab DG40" | Get-CfgIPAddress Gets the IPAddresses of members of collection Lab DG40 .NOTES Author: Jesse Harris For: University of Sunshine Coast Date Created: 09 Jan 2012 ChangeLog: 1.0 - First Release #> param( [Parameter(ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] [string[]]$ComputerName="$env:computername", $Site="SC1", $SiteServer="wsp-configmgr01.usc.internal") PROCESS { function Get-CfgIPWorker { Param($Name) (Get-CfgClientInventory -ComputerName $Name -Property IPAddresses).IPAddresses } If ($PSBoundParameters.ContainsKey('ComputerName')) { Foreach ($Computer in $ComputerName) { Get-CfgIPWorker -Name $Computer } } Else { Get-CfgIPWorker -Name $ComputerName } } } function Send-RepairCCM { <# .SYNOPSIS Attempts to repair a ConfigMgr client by sending a WMI method which uses MSI repair function. .DESCRIPTION Connects to the specified machines WMI namespace and runs a repair. If the Force parameter is used, the client is fully uninstalled and re-installed and the WMI repository is rebuilt. .PARAMETER ComputerName The hostname of a computer where you can connect and have administrator privileges. .PARAMETER Force Causes the client to be uninstalled, WMI service stopped, WMI repository renamed, WMI restarted and client re-installed. .EXAMPLE C:\PS>Send-RepairCCM 6wmpsn1 Uninstalling SCCM Client... Success Force option: Rebuilding WMI Stopping WMI Renaming Repository Renamed \\9k9562s\c$\windows\Syswow64\wbem\Repository Renamed \\9k9562s\c$\windows\system32\wbem\Repository Restarting WMI SharedAccess would not start CCMExec gone. re-installing... Success .NOTES Author: Jesse Harris For: University of Sunshine Coast Date Created: 09 Jan 2012 ChangeLog: 1.0 - First Release #> [CmdletBinding()] Param( [Parameter(Mandatory=$true,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] [string[]]$ComputerName,[Switch]$Force) PROCESS { function RepairCCM-Worker { Param($Name) If ($Force) { function Send-RemoteCommand { Param($Command,$Arguements,$ComputerName,[Switch]$NoWait) If ($NoWait) { $Options = "-d" } psexec.exe \\$ComputerName -s "$Command" $Arguements $Options 2>Null If ($LASTEXITCODE -eq 0) {Write-Host -ForegroundColor Green "Success" } Else {Write-Host -ForegroundColor Red "Fail"; return 1} } function Test-Service { Param($ServiceName,$ComputerName,$Action) $Service = Get-Service -ComputerName $ComputerName -Name $ServiceName If ( $Action -eq "Stop" ) {If ($Service.Status -eq "Running") {Try {$Service.Stop()} Catch {"$($Service.Name) would not stop"}}} If ( $Action -eq "Start") {If ($Service.Status -eq "Stopped") {Try {$Service.Start()} Catch {"$($Service.Name) would not start"}}} } #Setup Commands $InstallCommand = "\\wsp-configmgr01\SMS_SC1\Client\ccmsetup.exe /mp:wsp-configmgr01.usc.internal /force SMSSITECODE=SC1 SMSSLP=wsp-configmgr01.usc.internal DNSSUFFIX=USC.INTERNAL SMSMP=wsp-configmgr01.usc.internal" $UninstallCommand = "\\wsp-configmgr01\SMS_SC1\Client\ccmsetup.exe /Uninstall" #Get Architechture $SYS = "System32" $CCMSetup = "ccmsetup\Logs\ccmsetup.log" #Uninstall Client Write-Host "Uninstalling SCCM Client..." Send-RemoteCommand -ComputerName $Name -Command "C:\Windows\$SYS\cmd.exe" -Arguements "/c $UninstallCommand" Write-Host "Force option: Rebuilding WMI" Write-Host "Stopping WMI" Test-Service -ServiceName SharedAccess -ComputerName $Name -Action Stop Test-Service -ServiceName winmgmt -ComputerName $Name -Action Stop Start-Sleep -Seconds 10 Write-Host "Renaming Repository" $Repository = "\\$Name\c$\windows\Syswow64\wbem\Repository","\\$Name\c$\windows\system32\wbem\Repository" Foreach ( $Repo in $Repository ) { If (Test-Path $Repo) { Rename-Item -Path $Repo -NewName "Repo.Old"; Write-Host "Renamed $Repo" } } Write-Host "Restarting WMI" Test-Service -ServiceName winmgmt -ComputerName $Name -Action Start Test-Service -ServiceName SharedAccess -ComputerName $Name -Action Start Start-Sleep -Seconds 20 Write-Host "CCMExec gone. re-installing..." Send-RemoteCommand -ComputerName $Name -NoWait -Command "C:\Windows\$SYS\cmd.exe" -Arguements "/c $InstallCommand" Start-Sleep -Seconds 10 Start-Process cmtrace.exe \\$Name\c$\Windows\$CCMSetup While (!(Test-Path \\$Name\c$\Windows\ccm\logs\)) { Write-Host "Waiting for ccmexec to come online" Start-Sleep -Seconds 10 } Start-Process \\$Name\c$\Windows\ccm\logs\ } Else { $Client = [WMIClass]"\\$($Name)\root\CCM:SMS_Client" $Client.InvokeMethod("RepairClient","") } } If ($PSBoundParameters.ContainsKey('ComputerName')) { Foreach ($Computer in $ComputerName) { RepairCCM-Worker -Name $Computer } } Else { RepairCCM-Worker -Name $ComputerName } } } function Install-CCM { <# .SYNOPSIS Attempts to install ConfigMgr client by using PSEXEC. .DESCRIPTION Uses PSExec to connect to a machine and run ccmsetup with USC parameters. .PARAMETER ComputerName The hostname of a computer where you can connect and have administrator privileges. .PARAMETER Uninstall Causes the client to be uninstalled. .EXAMPLE C:\PS>Install-CCM 9k9562s PsExec v1.98 - Execute processes remotely Copyright (C) 2001-2010 Mark Russinovich Sysinternals - www.sysinternals.com C:\Windows\SysWOW64\cmd.exe exited on 9k9562s with error code 0. Success .NOTES Author: Jesse Harris For: University of Sunshine Coast Date Created: 10 April 2012 ChangeLog: 1.0 - First Release #> [CmdletBinding()] Param( [Parameter(Mandatory=$true,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] [string[]]$ComputerName,[Switch]$Uninstall,[Switch]$Install) PROCESS { function InstallCCM-Worker { Param($Name) $InstallCommand = "\\wsp-configmgr01\SMS_SC1\Client\ccmsetup.exe /mp:wsp-configmgr01.usc.internal /forceinstall SMSSITECODE=SC1 SMSSLP=wsp-configmgr01.usc.internal DNSSUFFIX=USC.INTERNAL SMSMP=wsp-configmgr01.usc.internal" $UninstallCommand = "\\wsp-configmgr01\SMS_SC1\Client\ccmsetup.exe /Uninstall" function Send-RemoteCommand { Param($Command,$Arguements,$ComputerName,[Switch]$NoWait) If ($NoWait) { $Options = "-d" } psexec.exe \\$ComputerName -s "$Command" $Arguements $Options If ($LASTEXITCODE -eq 0) {Write-Host -ForegroundColor Green "Success" } Else {Write-Host -ForegroundColor Red "Fail"; return 1} } #Get Architechture If ( ( Test-Path -path \\$Name\c$\Windows\Syswow64) ) { $SYS = "SysWOW64" $CCMSetup = "ccmsetup\Logs\ccmsetup.log" } Else { $SYS = "System32" $CCMSetup = "ccmsetup\Logs\ccmsetup.log" } If ($Uninstall) { Write-Host "Uninstalling SCCM Client..." Send-RemoteCommand -ComputerName $Name -Command "C:\Windows\$SYS\cmd.exe" -Arguements "/c $UninstallCommand" } else { Send-RemoteCommand -ComputerName $Name -NoWait -Command "C:\Windows\$SYS\cmd.exe" -Arguements "/c $InstallCommand" Start-Sleep -Seconds 10 Start-Process cmtrace.exe \\$Name\c$\Windows\$CCMSetup While (!(Test-Path \\$Name\c$\Windows\ccm\logs\)) { Write-Host "Waiting for ccmexec to come online" Start-Sleep -Seconds 10 } Start-Process \\$Name\c$\Windows\ccm\logs\ } } If ($PSBoundParameters.ContainsKey('ComputerName')) { Foreach ($Computer in $ComputerName) { InstallCCM-Worker -Name $Computer } } Else { InstallCCM-Worker -Name $ComputerName } } } New-Alias -Name ginv -Value Get-CfgClientInventory -Scope Global New-Alias -Name gip -Value Get-CfgIPAddress -Scope Global function Get-RecentMachines { Param($CollectionName,$AgentTimeSpan) $DaysAgo = (Get-Date).AddDays(-$AgentTimeSpan) Get-CfgCollectionMembers -Collection $CollectionName | ` Get-CfgClientInventory | ` ForEach-Object { $Index = [array]::IndexOf($_.AgentName,"Heartbeat Discovery") If (($Index -gt -1) -and ([datetime]::ParseExact($_.AgentTime[$Index],"yyyyMMddHHmmss.000000+***",$null) -gt $DaysAgo)) { $_ | Select-Object @{label='ComputerName';expression={$_.Name}},@{label='Domain';expression={$_.ResourceDomainORWorkgroup}},LastLogonUserName,IPAddresses,@{label='AgentIndex';expression={$Index}},@{label='AgentTime';expression={Get Date $_.AgentTime[$Index]}} } } } function Get-AdvertisementResult { <# .SYNOPSIS Retreive Status of an/all Advertisment(s) from the SCCM primary site server for a specfic computer. .DESCRIPTION Connects to the primary site server and queries the WMI namespace for advertisement status. .PARAMETER AdvertID The ID of an Advertisment on the SCCM Site. Format example: USC20746 .PARAMETER ComputerName The name of a computer to query against. .EXAMPLE C:\PS>Get-AdvertisementResults -ComputerName B1HM52S ComputerName : B1HM52S AdvertisementID : USC20662 Status : Retrying LastStatusTime : 20130418230349.480000+*** AdvertisementName : Visual3D_Reader - [Virtual application] to Application Tester User ComputerName : B1HM52S AdvertisementID : USC2071E Status : Retrying LastStatusTime : 20130418230349.450000+*** AdvertisementName : XPanels - [Virtual application] to Crestron XPanels 1.0 USR .EXAMPLE C:\PS>Get-CfgCollectionMembers "Lab HG31" | Get-AdvertisementResults Command is usefull for gathering the overall success/failure of advertisements in a venue. .NOTES Author: Jesse Harris For: University of Sunshine Coast Date Created: 20 June 2013 ChangeLog: 1.0 - First Release #> [CmdLetBinding()] Param( [Parameter( ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$true, Mandatory=$true)]$ComputerName, $AdvertID, $SiteServer="wsp-configmgr01",$SiteCode="SC1") Process { If ($ComputerName.ComputerName) { $Name = $ComputerName.ComputerName } Else { $Name = $ComputerName } Get-WMIObject -ComputerName $SiteServer -Namespace "root\sms\site_$($SiteCode)" -Query ` "Select ResourceID from SMS_R_System Where Name like '$Name'" | ForEach-Object { $ResourceID = $_.ResourceID If ($AdvertID) { $Query = "Select AdvertisementID,LastStateName,LastStatusTime From SMS_ClientAdvertisementStatus Where ResourceID = '$ResourceID' and AdvertisementID = '$AdvertID'" } Else { $Query = "Select AdvertisementID,LastStateName,LastStatusTime From SMS_ClientAdvertisementStatus Where ResourceID = '$ResourceID'" } $AdvObj = Get-WMIObject -ComputerName $SiteServer -Namespace "root\sms\site_$($SiteCode)" -Query $Query | Select @{LABEL='ComputerName'; Expression={$Name}},AdvertisementID,@{LABEL='Status'; Expression={$_.LastStateName}},LastStatusTime ForEach ($Adv in $AdvObj) { $AdvID = $Adv.AdvertisementID $AdvName = (Get-WMIObject -ComputerName $SiteServer -Namespace "root\sms\site_$($SiteCode)" -Query "Select AdvertisementName From SMS_Advertisement Where AdvertisementID = '$AdvID'").AdvertisementName $Adv | Add-Member -MemberType NoteProperty -Name AdvertisementName -Value $AdvName -PassThru } } } } function Get-MachineInventory { <# .SYNOPSIS Retreive Inventory information of a USC computer from ActiveDirectory and Config Manager. .DESCRIPTION Connects to the primary site server and queries the WMI namespace for client inventory, Connects to AD and gathers group data and description. .PARAMETER ComputerName The name of a client computer, registered with the Site Server. .EXAMPLE C:\PS>Get-MachineInventory 6WMPSN1 LastedLogonUserName : jpharris ADCreated : 6/05/2011 1:01:47 PM ADPath : usc.internal/MOEDev/DevWorkstations/Staff/6WMPSN1 DockStatus : ADIPAddress : ADMemberOf : OU : STAFF MonitorRes : ComputerName : 6wmpsn1 MonitorCount : Model : Virtual Machine ADDescription : M6500 - JPHarris SetBy Jpharris WKSGROUP : VLAN : Virtual Server (Test / Dev Network) ADPWDLastSet : 17/09/2012 9:17:38 AM LastHeartbeat : 5/10/2012 8:52:07 AM Memory : 1,606 MB ADOperatingSystem : Windows 7 Enterprise .EXAMPLE C:\PS>Import-CSV C:\Computers.csv | ForEach-Object { Get-MachineInventory -ComputerName $_."Column A" } | Export-CSV C:\ComputerInventory.csv This command will get the machine inventory for each computer in the column titled "Column A" from the Computers.csv file. .EXAMPLE C:\PS>Get-MachineInventory 6WMPSN1 | Select ComputerName,DockStatus Returns just the computername and dockstatus properties .EXAMPLE C:\PS>Get-CfgCollectionMembers -Collection "Latitude E Series" | Get-MachineInventory Returns the machine inventory for all computers in the SCCM collection "Latitude E Series" .NOTES Author: Jesse Harris For: University of Sunshine Coast Date Created: 05 Oct 2012 ChangeLog: 1.0 - First Release #> [CmdLetBinding()] Param( [Parameter( ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$true, Mandatory=$true)]$ComputerName, $AdvertID, $SiteServer="wsp-configmgr01",$SiteCode="SC1") Begin { #Check if SCCM Module is available and loaded #Write-Host -ForegroundColor Cyan "Checking modules..." $Modules = "ActiveDirectory","USC-SCCM","USC-DellWarranty","Import-Excel","USC-VLAN" ForEach ($Module in $Modules) { If (!(Get-Module -Name $Module)) { If (Get-Module -ListAvailable | Where-Object {$_.Name -eq $Module}) { Write-Host -ForegroundColor Cyan "Loading $Module module..." Import-Module $Module } Else { Write-Host -ForegroundColor Red "$Module module not available" Return 1 } } } } Process { function Get-MachineInventoryWorker { Param($Name) If ($SCCMInventory = Get-CfgClientInventory -ComputerName $Name -Properties Monitor,Model,Memory) { $SCCMInventory.SystemGroupName | Where-Object {(($_ -notmatch "SCCM") -and ($_ -notmatch "Domain Computers")) -or ($_ -match "MGSProd WKS")} | ForEach-Object {$WKSGroup += $($_ -replace "USC\\*","") + " "} $Index = [array]::IndexOf($SCCMInventory.AgentName,"Heartbeat Discovery") If ($Index -gt -1) { $HeartBeatDate = [datetime]::ParseExact($SCCMInventory.AgentTime[$Index],"yyyyMMddHHmmss.000000+***",$null) } } If ($ADInventory = Get-ADComputer -Identity $Name -Properties MemberOf,Description,Created,CanonicalName,PasswordLastSet,OperatingSystem,IPv4Address) { $ADInventory.MemberOf | Where-Object {($_ -notmatch "SCCM")} | ForEach-Object {$ADGroups += $($_) + " "} } If ($SCCMInventory.LastLogonUserName) { $ADUser = Get-ADUser -Identity $SCCMInventory.LastLogonUserName -Properties ExtensionAttribute14,mail,DistinguishedName,memberof } New-Object -TypeName PSObject -Property @{ 'ComputerName' = $Name 'MonitorCount' = $SCCMInventory.MonitorCount 'MonitorRes' = $SCCMInventory.MonitorRes 'Memory' = $SCCMInventory.Memory 'LastLogonUserName' = $SCCMInventory.LastLogonUserName 'LastHeartbeat' = $HeartBeatDate 'WarrantyEndDate' = (Get-DellWarrantyStatus -ComputerName $Name).WarrantyEndDate 'OU' = $SCCMInventory.SystemOUName[$SCCMInventory.SystemOUName.Count-1] -replace ".*/","" 'WKSGROUP' = $WKSGroup 'Model' = $SCCMInventory.Model 'ADMemberOf' = $ADGroups 'ADDescription' = $ADInventory.Description 'ADCreated' = $ADInventory.Created 'ADPath' = $ADInventory.CAnonicalName 'ADPWDLastSet' = $ADInventory.PasswordLastSet 'ADOperatingSystem' = $ADInventory.OperatingSystem 'ADIPAddress' = $ADInventory.IPv4Address 'VLAN' = (Get-VLANFromIPAddress -IPAddress $ADInventory.IPv4Address) 'UserExtensionAttribute14' = $ADUser.Extensionattribute14 'UserMail' = $ADUser.mail 'UserPath' = $ADUser.DistinguishedName 'UserGroupMembers' = $ADUser.memberof } } If ($PSBoundParameters.ContainsKey('ComputerName')) { Foreach ($Computer in $ComputerName) { If ($Computer.ComputerName) { Get-MachineInventoryWorker -Name $Computer.ComputerName } Else { Get-MachineInventoryWorker -Name $Computer } } } Else { Get-MachineInventoryWorker -Name $ComputerName } } } function Get-AdvertisementStatus { <# .SYNOPSIS Retreive Status of an Advertisment from the SCCM primary site server. .DESCRIPTION Connects to the primary site server and queries the WMI namespace for advertisement status. .PARAMETER AdvertID The ID of an Advertisment on the SCCM Site. Format example: USC20746 .EXAMPLE C:\PS>Get-AdvertisementStatus USC20746 ComputerName LastStateName ------------ ------------- 8KLF6R1 Retrying 7QNQ12S Failed GBRS62S Failed 4K9562S Failed HCQ6FS1 Failed 4WHNBS1 Failed DTT5D2S Failed .EXAMPLE C:\PS>Import-CSV C:\Computers.csv | ForEach-Object { Get-MachineInventory -ComputerName $_."Column A" } | Export-CSV C:\ComputerInventory.csv This command will get the machine inventory for each computer in the column titled "Column A" from the Computers.csv file. .EXAMPLE C:\PS>Get-MachineInventory 6WMPSN1 | Select ComputerName,DockStatus Returns just the computername and dockstatus properties .EXAMPLE C:\PS>Get-CfgCollectionMembers -Collection "Latitude E Series" | Get-MachineInventory Returns the machine inventory for all computers in the SCCM collection "Latitude E Series" .NOTES Author: Jesse Harris For: University of Sunshine Coast Date Created: 05 Oct 2012 ChangeLog: 1.0 - First Release #> [CmdLetBinding()] Param( [Parameter( ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$true, Mandatory=$true)]$AdvertID="USC20746", $SiteServer="wsp-configmgr01",$SiteCode="SC1",$State) Process { switch ($State) { Failed { $Query = "Select ResourceID,LastStateName From SMS_ClientAdvertisementStatus Where AdvertisementID = '$AdvertID' and LastStateName = 'Failed'" } Succeeded { $Query = "Select ResourceID,LastStateName From SMS_ClientAdvertisementStatus Where AdvertisementID = '$AdvertID' and LastStateName = 'Succeeded'" } NoStatus { $Query = "Select ResourceID,LastStateName From SMS_ClientAdvertisementStatus Where AdvertisementID = '$AdvertID' and LastStateName = 'No Status'" } Accepted { $Query = "Select ResourceID,LastStateName From SMS_ClientAdvertisementStatus Where AdvertisementID = '$AdvertID' and LastStateName LIKE 'Accepted%'" } default { $Query = "Select ResourceID,LastStateName From SMS_ClientAdvertisementStatus Where AdvertisementID = '$AdvertID'" } } Get-WMIObject -ComputerName $SiteServer -Namespace "root\sms\site_$($SiteCode)" -Query $Query | Select @{LABEL='ComputerName'; Expression={$Resource = $_.ResourceID; (Get-WMIObject -ComputerName $SiteServer -Namespace "root\sms\site_$($SiteCode)" -Query "Select Name from SMS_R_System Where ResourceID = '$Resource'").Name}},LastStateName } } function Get-CurrentUser { Param( [Parameter( ValueFromPipeLine = $true, ValueFromPipelinebyPropertyName = $True)] $ComputerName=$env:ComputerName) Process { If ($ComputerName.ComputerName) { $Computers = $ComputerName.ComputerName } Else { $Computers = $ComputerName } Foreach ($ComputerName in $Computers) { If (Test-Connection -ComputerName $ComputerName -Quiet -Count 1 -TTL 5) { Get-WmiObject -ComputerName $ComputerName -Class Win32_computersystem | Select -Property @{label='UserName'; expression={$_.UserName.TrimStart("USC\")}},@{label='ComputerName';expression={$ComputerName}} } } } } function Invoke-CfgConfigEval { <# .SYNOPSIS Evaluate Configuration baslines assigned to a configuration manager client. .DESCRIPTION Connects to a client machine WMI namespace and executes a method on a named configuration item or all configuration itmes. .PARAMETER ComputerName The name of a client computer, with Configuration Manager client installed. .EXAMPLE C:\PS>Invoke-CfgConfigEval D8MN52S __GENUS : 1 __CLASS : __PARAMETERS __SUPERCLASS : __DYNASTY : __PARAMETERS __RELPATH : __PARAMETERS __PROPERTY_COUNT : 2 __DERIVATION : {} __SERVER : D8MN52S __NAMESPACE : ROOT\ccm\dcm __PATH : \\D8MN52S\ROOT\ccm\dcm:__PARAMETERS JobId : {12BF6F7D-B533-4361-83C3-6B407F07A83F} ReturnValue : 0 PSComputerName : D8MN52S .EXAMPLE C:\PS>Get-CfgCollectionMembers "Lab H107" | Invoke-CfgConfigEval This command will retrieve all members of the collection "Lab H107" and attempt to connect to each machines WMI to evaluation configuration baselines. .EXAMPLE C:\PS>Invoke-CfgConfigEval -ComputerName BSYQXY1 -Name Application-Shortcut-NVR Attempts to evaluate only baseline "Application-Shortcut-NVR" .NOTES Author: Jesse Harris For: University of Sunshine Coast Date Created: 01 May 2014 ChangeLog: 1.0 - First Release #> Param([Parameter( ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$true, Mandatory=$true)]$ComputerName=$env:COMPUTERNAME, [Parameter( ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$True)]$DisplayName) Process { function Config-Worker { Param($Computer) If ($DisplayName.DisplayName) { $DisplayName = $DisplayName.DisplayName } $DCMTrigger = [WMIClass]"\\$Computer\Root\CCM\DCM:SMS_DesiredConfiguration" If ($DisplayName) { $Query = 'Select * from SMS_DesiredConfiguration where DisplayName = "' + $DisplayName + '"' } Else { $Query = 'Select * from SMS_DesiredConfiguration' } $Configurations = Get-WmiObject -ComputerName $Computer -Namespace Root\CCM\DCM -Query $Query ForEach ($Config in $Configurations) { $Config.Name $Config.Version $DCMTrigger.TriggerEvaluation($Config.Name,$Config.Version) } } If ($PSBoundParameters.ContainsKey('ComputerName')) { Foreach ($Computer in $ComputerName) { If ($Computer.ComputerName) { Config-Worker -Computer $Computer.ComputerName } Else { Config-Worker -Computer $Computer } } } Else { Config-Worker -Computer $ComputerName } } } function Get-CfgConfigEval { <# .SYNOPSIS Get Configuration baselines assigned to a configuration manager client. .DESCRIPTION Connects to a client machine WMI namespace and retreives a configuration item or all configuration itmes. .PARAMETER ComputerName The name of a client computer, with Configuration Manager client installed. .PARAMETER DisplayName The Displayname of a configuration item .EXAMPLE C:\PS>Get-CfgConfigEval D8MN52S ComputerName : DCG2GY1 DisplayName : Application-Setting-Flash AutoUpdateDisable IsMachineTarget : True LastEvalTime : 3/06/2014 12:39:59 AM LastComplianceStatus : 1 Status : 0 Version : 4 ComputerName : DCG2GY1 DisplayName : Application-Presence-Adobe Acrobat 10 IsMachineTarget : True LastEvalTime : 3/06/2014 12:48:18 AM LastComplianceStatus : 1 Status : 0 Version : 2 .EXAMPLE C:\PS>Get-CfgCollectionMembers "Lab H107" | Get-CfgConfigEval This command will retrieve all members of the collection "Lab H107" and attempt to connect to each machines WMI to list configuration baselines. .EXAMPLE C:\PS>Get-CfgConfigEval -ComputerName BSYQXY1 -DisplayName Application-Shortcut-NVR Attempts to list only baseline "Application-Shortcut-NVR" .NOTES Author: Jesse Harris For: University of Sunshine Coast Date Created: 06 June 2014 ChangeLog: 1.0 - First Release #> Param([Parameter( ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$true, Mandatory=$true)]$ComputerName=$env:COMPUTERNAME,$DisplayName) Process { function Config-Worker { Param($Computer) If ($DisplayName) { $Qeury = "Select * from SMS_DesiredConfiguration where DisplayName = ""$DisplayName""" } Else { $Qeury = "Select * from SMS_DesiredConfiguration" } Get-WmiObject -ComputerName $Computer -Namespace Root\CCM\DCM -Query $Qeury | ForEach-Object { Switch ($_.LastComplianceStatus) { 0 {$LastComplianceStatus = 'Non-Compliant'} 1 {$LastComplianceStatus = 'Compliant'} Default {$LastComplianceStatus = 'Error'} } [pscustomobject]@{ 'ComputerName' = $_.PSComputerName 'DisplayName' = $_.DisplayName 'IsMachineTarget' = $_.IsMachineTarget 'LastEvalTime' = If ($_.LastEvalTime) {[datetime]::ParseExact($_.LastEvalTime,'yyyyMMddHHmmss.000000+000',$null)} Else {$null} 'LastComplianceStatus' = $LastComplianceStatus 'Status' = $_.Status 'Version' = $_.Version } } } If ($PSBoundParameters.ContainsKey('ComputerName')) { Foreach ($Computer in $ComputerName) { If ($Computer.ComputerName) { Config-Worker -Computer $Computer.ComputerName } Else { Config-Worker -Computer $Computer } } } Else { Config-Worker -Computer $ComputerName } } } function Get-CfgCollectionsByFolder { <# .SYNOPSIS Get Collections based on their administrative assigned folder. .DESCRIPTION Connects to the primary site server, and returns collections which are contained in a folder. .PARAMETER FolderName The name of a folder containing device collections. .PARAMETER SiteServer The hostname of the primary site server. .EXAMPLE C:\PS>Get-CfgCollectionsByFolder -FolderName 'Software Distribution' FolderName CollectionName CollectionID LimitingCollection ---------- -------------- ------------ ------------------ Software Distribution Adobe Presenter 8 MSI WKS-Install SC100014 All Systems Software Distribution Adobe Presenter 8 MSI WKS-Uninstall SC100015 All Systems Software Distribution ClimSystems TrainClim 2.0.0.31 MSI WKS SC100019 All Systems Software Distribution ClimSystems TrainClim 2.0.0.31 MSI WKS-Install SC10001A ClimSystems TrainClim 2.0.0.31 MS.. Software Distribution ClimSystems TrainClim 2.0.0.31 MSI WKS-Uninstall SC10001B All Systems Software Distribution Google Google Chrome 23.0.1271.97 MSI WKS SC10001C All Systems Software Distribution Google Google Chrome 23.0.1271.97 MSI WKS-Install SC10001D Google Google Chrome 23.0.1271.97.. .EXAMPLE C:\PS>Get-CfgCollectionsByFolder -FolderName 'Software Distribution' | ? LimitingCollection -eq "All USC Managed Computers" | %{Set-CMDeviceCollection -CollectionId $_.CollectionID -LimitToCollectionID SC100030 This command will retrieve all collections under the 'Software Distribution' folder which are currently limited to collection name 'All USC Managed Computers' and limit them to 'All USC Non-Volatile Computers' .EXAMPLE C:\PS>Get-CfgCollectionsByFolder -FolderName 'Software Distribution' -UserCollection This command will retrieve user collections by user foldername. .NOTES Some of the examples in this help, depend on the official Configuration Manager module Author: Jesse Harris For: University of Sunshine Coast Date Created: 17 May 2016 ChangeLog: 1.0 - First Release #> [CmdLetBinding()] Param([Parameter(Mandatory=$True)]$FolderName,$SiteServer="wsp-configmgr01",$SiteCode="SC1",[switch]$UserCollection) If ($UserCollection) { $objectType = 'SMS_Collection_User' } Else { $objectType = 'SMS_Collection_Device' } $InstanceKey = Get-WmiObject -ComputerName $SiteServer -Namespace "root\sms\site_SC1" -Query "Select * from SMS_ObjectContainerNode Where objectTypeName = '$objectType'" | Where-Object {$_.Name -eq $FolderName} If (-Not $InstanceKey) { Write-Error -Category ObjectNotFound -Message "No Configuration manager folder named $FolderName could be found" return } Get-WmiObject -ComputerName $SiteServer -Namespace "root\sms\site_$SiteCode" -Query "select * from SMS_ObjectContainerItem where ContainerNodeID = '$($InstanceKey.ContainerNodeID)'" | ForEach-Object { Get-WmiObject -ComputerName $SiteServer -Namespace "root\sms\site_$SiteCode" -Query "select * from SMS_Collection where CollectionID = ""$($_.InstanceKey)"""} | %{ [PSCustomObject]@{ 'FolderName' = $FolderName; 'CollectionName' = $_.Name; 'CollectionID' = $_.CollectionID 'LimitingCollection' = $_.LimitToCollectionName } } } function Get-CfgCollectionsDeps { <# .SYNOPSIS Get a list of collections which are limited to a specific collection. .DESCRIPTION Connects to the primary site server WMI namespace and retreives a values from SMS_CollectionDependancies. .PARAMETER CollectionName The name of a source collection to which other collections are limited to. .PARAMETER SiteServer The hostname of the primary site server .EXAMPLE C:\PS>Get-CfgCollectionsDeps 'All USC Managed Computers' SourceCollectionID DependentCollectionID ------------------ --------------------- SC10025C SC100030 SC10025C SC100413 SC10025C SC100414 SC10025C SC100444 SC10025C SC100500 SC10025C SC10051C .EXAMPLE C:\PS>Get-CfgCollectionDeps "All USC Managed Computers" | ForEach-Object {Set-CMDeviceCollection -Id $_.DependentCollectionID -LimitToCollectionId SC100030 -WhatIf} This command will update the limiting collection of all collections currently limited to 'All USC Managed Computers' .NOTES Author: Jesse Harris For: University of Sunshine Coast Date Created: 17 May 2016 ChangeLog: 1.0 - First Release #> [CmdLetBinding()] Param([Parameter(Mandatory=$True)]$CollectionName,$SiteServer="wsp-configmgr01",$SiteCode="SC1") $CollectionID = (Get-WmiObject -ComputerName $SiteServer -Namespace "root\sms\site_$SiteCode" -Query "Select CollectionID from SMS_Collection Where Name = '$CollectionName'").CollectionID If (-Not $CollectionID) { Write-Error -Category ObjectNotFound -Message "No collection with name $CollectionName could be found" return } $CollectionDeps = Get-WmiObject -ComputerName $SiteServer -Namespace "root\sms\site_SC1" -Query "select * from SMS_CollectionDependencies where SourceCollectionID='$CollectionID'" If (-Not $CollectionDeps) { Write-Error -Category ObjectNotFound -Message "No collection references of $CollectionName could be found" return } #Select distinct SourceCollectionID, DependentCollectionID from SMS_CollectionDependencies where SourceCollectionID='SC10047B' $CollectionDeps | Select SourceCollectionID,DependentCollectionID } |