Posts

Showing posts from 2016

Triggering a software update install via Powershell

Howdy Folks This post is a holiday slice of pie. Today we focus on triggering update(s) that are deployed to a machine. Now for the pie filling. Triggering an update scan on a client: ([wmiclass]'ROOT\ccm:SMS_Client').TriggerSchedule('{00000000-0000-0000-0000-000000000113}') Trigger install of all updates: ([wmiclass]'ROOT\ccm\ClientSDK:CCM_SoftwareUpdatesManager').InstallUpdates() Here is a nice addition if you only want to install specific update(s) you just have to modify the select statement: ([wmiclass]'ROOT\ccm\ClientSDK:CCM_SoftwareUpdatesManager').InstallUpdates([System.Management.ManagementObject[]] (get-wmiobject -query 'SELECT * FROM CCM_SoftwareUpdate' -namespace 'ROOT\ccm\ClientSDK')) If you would like to see if there are updates applying, if true they are running: $CCMUpdate = get-wmiobject -query "SELECT * FROM CCM_SoftwareUpdate" -namespace "ROOT\ccm\ClientSDK" if(@($CCMUpdate | where {

Some reports break in SSRS after SQL 2012 to 2014 upgrade

Greetings Follow Professionals We had an interesting one when updated from SQL 2012 to SQL 2014 and SSRS reports. We found that it didn't break all reports just some. Anyways a teammate of mine found the following blog post that ended up addressing and fixing our issue.  I just wanted to share it so that others are aware. https://ronnydejong.com/2013/05/23/reporting-service-point-rsp-broken-after-upgrading-sql-server-2012-sp1-sysctr/ The just of it is updating the path in the rssrvpolicy.config file to point to the new SSRS directory and to copy the srsresources.dll file to the new directory.

Specialized Application Reporting - Part 3

Image
Welcome to Part 3 of this 3 Part Series. In this portion we will discuss actually using the data that you created in 2 of this series. Now there are a few ways you can do this, you can create a SSRS report, or a Excel spreadsheet with datalinks, or create a Power BI report. My teammate opted for the Power BI Report which I have included the report file that you can download. There are a couple of variables in it that will need to be updated so that it connects to the database and data that we created in this series. Here is a download of the Power  BI Report file  in order to open the file you will need Power BI Desktop which is free from Microsoft. Just go to the Edit Queries and add your information. If you use Power BI you can get a nice colorful report looking something like the following: If you don't want to mess with Power BI or you have your own preferred way of creating reports. Here are the queries used in the Power BI file that loads the da

Specialized Application Reporting - Part 2

Welcome to Part 2 of this 3 Part Series. In this portion we will discuss building the data that you need for part 3 of this series. This is where things will get a bit confusing but I will try to make it make sense. A couple of points to remember upfront: All variables used in the WHERE statements are LIKE clauses. Examples shown are setup to handle an application deployment that is using more than one collection. Where you see [ ] fill in with your environment information These steps are designed to be used in a SQL Job and ran on a schedule, however I recommend running manually while you make sure everything is working as it should first. Step #1 - Update the vAppDeploymentResultsPerClient table USE [INSERT DB NAME HERE] DECLARE @AppName varchar(max) DECLARE @CollectionName1 varchar(max) DECLARE @CollectionName2 varchar(max) SET @AppName = '[ApplicationName]' SET @CollectionName1 = '[CollectionName]' SET @CollectionName2 = '[CollectionName]

Specialized Application Reporting - Part 1

Welcome to Part 1 of this 3 Part Series. In this portion we will discuss the groundwork that will be used in part 2 and 3 of this series. It is recommended to do all this in a database that is not the CM database. Ideally you would have a database just for this (and on a different server, like say a dedicated reporting point). If you use a different server than the one containing your CM database. You will need to setup a Link Server for the queries to get data from the CM database. Now for the why are we doing this? Well this stemmed from one of my teammates getting tired of running the same queries over and over again for a project. Part 2 of this series will focus on the portion that can be turned into jobs that can run on a schedule. Part 3 will focus on giving a nice and pretty report that can be used for your own desires or to show others who like pretty colors. Setting up your tables: Below is the SQL required to setup the tables and view that will be used in part 2 an

Using Powershell to Assign iOS devices to DEP profile

Image
Hello fellow admins! As you can guess from the title, this post is dealing with a SCCM/Intune hybrid environment scenario. If you are in a hybrid environment you have probably noticed that using Apple DEP is a bit different than just using the Portal app on the phone. With that said, if you happen to be lucky enough to be able to delegate the mobile device management to another group. Then you will have probably also noticed that you can't limit security permissions below full admin if you want them to be able to assign devices to DEP. Well have no fear, here is a nifty bit of powershell that you can setup to run on a schedule (hint: think CI). This handy script will lookup mobile devices and then assign them. Basically it does what this dialog does. Now to the nitty gritty. First off I recommend you familiarize yourself with the MSDN technical documentation for the method  UpdateProfileIDForDevices , however what this documentation doesn't tell you is where the heck do

Computer Monitor Inventory Data Query

Greetings Folks! Today's post is going to talk about computer monitor inventory data. While I have found a good post from a Technet blog to get you started, I've had to modify the query referenced in that blog. As I found their query to be a bit on the broken side. So naturally I fixed it. Also you don't have to go through the whole modifying the mof file to collect the monitor data. There is actually already a WMI class in windows so you just have to go into the default client settings for hardware inventory and add/select the class. The class you need is WMIMONITORID The neat thing about this WMI class is that the monitor model is stored in ASCI numeric comma separated values. So you get to convert it letter by letter (or should I say two numbers by two numbers). In order to do the conversion, we are using a cursor. While some of you SQL experts out there may say that this is not the most elegant method. It gets the job done, be it a bit slowly. Anyways now to

Powershell to submit unidentified software in SCCM Asset Intelligence

Hello folks Have you ever thought "There's got to be an easier way than doing 100 at a time" when you are choosing software to upload to MSFT for AI identification? Well then you are in luck for here is a little something to make it easier on you. *Common note, please make sure you control how many you do. Otherwise you will probably overload things. Get the AI Software objects that are unknow. $wsql = "Select * from SMS_AISoftwareList Where State = 4" $output = Get-WmiObject -Query $wsql -Namespace "root\sms\site_code" -ComputerName "YourServer" Then just add your logic for looping the update. foreach ($app in $output) {    ([wmiclass]'\\YourServer\root\sms\site_code:SMS_AISoftwareList').SetCategorizationRequest($app.SoftwareKey)   } Now you can just sit back and watch the provider log roll. However it is a better idea to only do the apps that you know need to be uploaded. So you can add items to your query to remove

Using Powershell for automating Software Updates

Found a really neat blog from another blog that I found really neat and useful. I recommend you give it a read. From how he is doing it, you could easily combine it with a script that reads from another server/update group and use it to "copy" the update setup/deployment from one to another. Great idea for handling your test/dev machines. Give it a read at: http://www.dexterposh.com/2014/06/powershell-sccm-2012-automate-patching.html

CI guts for App Catalog check

Greetings everyone! If you are following in my footsteps of exposing the App Catalog web services. Here are a few tibbits that could help you keep your services exposed. Create a CI and use the following in the detection method. $registryPath = "HKLM:\Software\Microsoft\SMS\PORTALWEB" $registryName = "PortalPath" $key = Get-ItemProperty -Path $registryPath -Name $registryName $FilePath = $key.PortalPath+"\default.aspx" $ConfigFile = $key.PortalPath+"\web.config" $WebConfig1 = [System.IO.File]::ReadAllText($ConfigFile) $WSDLVisble = $WebConfig1.Contains("<!--<remove name=""Documentation"" />-->") -or $WebConfig1.Contains("<!--<remove name=""Documentation""/>-->") -or (!($WebConfig1.Contains("<remove name=""Documentation"" />"))) Remediation (if you choose to be so brave). $registryPath = "HKLM:\Software\Micr

Starting/Stopping a thread of the SCCM executive

So it has been a while since I've posted. Here is something a bit nifty for you. Have you ever needed to programmatically start (or restart) an individual thread in SCCM and you don't want to mess with the Service Control GUI in the console? Well here is a nifty little script for you. You can also find the thread status in that same registry location. ----------------------------------- param( [string] $thread = "SMS_DMP_DOWNLOADER", [string] $action = "Start" ) $registryPath = "HKLM:\Software\Microsoft\SMS\Components\SMS_Executive\Threads\$thread" $registryName = "Requested Operation" #$key = Get-ItemProperty -Path $registryPath -Name $registryName Set-ItemProperty -Path $registryPath -Name $registryName -Value $action --------------------------------

Prestaging/Extracting Content

Here is another take on the creating of prestaged content and extracting content from one of my teammates. He did state that it does require Powershell 3 and higher to run. Also to note the extract content script will delete the prestage files once they have been extracted, however you can change the comments around and it will just move them to a done folder instead of deleting them. The extract content one uses the extract folder parameter instead of the actual file name to get around the character limit on a the parameter length. Prestage All Content if ([Environment]::Is64BitProcess) {Read-Host "This must be run from 32-bit Powershell";exit} $SiteCode = "PRI" $Server = "PrimaryServer" $DP = "DistributionPointServer" $FolderToSaveTo = "C:\PrestageContent" Import-Module "C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1" #$Overwrite = $true $Overwrite = $false $N

Stuck @ "Waiting for user logon"

This may or may not be something that you would commonly see in your environment. We only see it occasionally but it used to be a pretty common problem. One of my teammates found a technet forum post that addressed this specifically. Pretty interesting read if you are fighting this issue on a particular client. https://social.technet.microsoft.com/Forums/en-US/1569e1e2-91bc-435d-8998-beb817d5b453/waiting-for-user-logon?forum=configmanagergeneral Here is the meat and potatoes of the forum discussion. $CITask = get-wmiobject -query "select * from CCM_CITask where TaskState != ' PendingSoftReboot' AND TaskState != 'PendingHardReboot' AND TaskState != 'InProgress'" -namespace root\ccm\CITasks if ($CITask -ne $NULL) { $CITask | remove-wmiobject -Whatif $CITask | remove-wmiobject } ELSE { "CCM_CITasks is empty. Nothing to do" }

Create RDL files in mass

I found this script a while back when we were doing some reporting server migrations. Not sure how useful you might find this script as it is a bit dated and I'm sure there are newer calls that can be done to accomplish the same feat. #note this is tested on PowerShell v2 and SSRS 2008 R2 [void][System.Reflection.Assembly]::LoadWithPartialName("System.Xml.XmlDocument"); [void][System.Reflection.Assembly]::LoadWithPartialName("System.IO"); $ReportServerUri = "http://ServerName/ReportServer/ReportService2005.asmx"; $Proxy = New-WebServiceProxy -Uri $ReportServerUri -Namespace SSRS.ReportingService2005 -UseDefaultCredential ; #check out all members of $Proxy #$Proxy | Get-Member #http://msdn.microsoft.com/en-us/library/aa225878(v=SQL.80).aspx #second parameter means recursive $items = $Proxy.ListChildren("/", $true) | `          select Type, Path, ID, Name | `          Where-Object {$_.type -eq "Report"}; #create a

Redistribute Specific Package on Specific DP

A simple little script to refresh content on a DP. The script uses a list of PackageIDs (yes even applications have a package id). The script also uses part of the DP server name to identify it. Import-Module -Name "C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1" cd DEV: $a = Get-Content "i:\temp\temp.txt" foreach ($i in $a)     {       $distpoints = Get-WmiObject -Namespace "\\bvlsccmcas\root\SMS\Site_CAS" -Query "Select * From SMS_DistributionPoint WHERE PackageID='$i' AND ServerNALPath like '%PER%'"     foreach ($dp in $distpoints)          {                  $dp.RefreshNow = $true                  $dp.Put()          }     }

Add Machine to a Collection

Here is another simple little script for doing a mass add of Machine Direct rules to a SCCM collection. Note: You will need to have the console installed on the machine that you run this script from due to the powershell cmdlets required. Import-Module -Name "C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1" $a = Get-Content "i:\temp\temp.txt" foreach ($i in $a)     {     $i | Out-File -FilePath c:\temp\assignout.log -Append     $device = get-cmdevice -Name $i     Add-CMDeviceCollectionDirectMembershipRule -CollectionName "Collection Name" -Resource $device | Out-File -FilePath c:\temp\assignout.log -Append     }

Add Computers to AD Group

Here is a simple little script for adding a mass number of machines to an AD Group. Note: You will need to make sure you have the AD Powershell module installed on the machine you run this on. Import-Module ActiveDirectory $ADGroup = "AdGroup" $Members = Get-ADGroupMember -Identity $ADGroup $Machines = get-content "E:\Powershell Script\AddMachinesToADGroup.txt" $Failures = @() $Added = @() $Existing = @() Foreach ($Machine in $Machines) {     if ($Machine -in $Members.SAMAccountName)     {         $Existing += $Machine     }     else     {         try {             $Machine += "$"             "Trying to Add $($Machine)"             Add-ADGroupMember -Identity $ADGroup -Members $Machine             $Added += $Machine           }         catch { $Failures += $Machine }     } }

Create Prestaged Content and Extract Content

One of my teammates recently created a couple of scripts that we use frequently when doing server migrations and building out new sites. Extract Content $Folder = "Packages" $FolderToSaveTo = "I:\PrestageContent\_Done" if(!(Test-Path $FolderToSaveTo\$Folder)) {New-Item -ItemType Directory -Path $FolderToSaveTo\$Folder} if(!(Test-Path I:\PrestageContent\$Folder\DoIt)) {New-Item -ItemType Directory -Path I:\PrestageContent\$Folder\DoIt} (Get-ChildItem -Path I:\PrestageContent\$Folder -Recurse -Include *.pkgx).Name | ForEach-Object { #$Name = $_ Write-Host "`n" "Files Left: " ((Get-ChildItem -Path I:\PrestageContent\$Folder -Recurse -Include *.pkgx) | Measure-Object).Count "`n" & Write-Host $_.TrimEnd(".pkgx") "`n" & Move-Item I:\PrestageContent\$Folder\$_ I:\PrestageContent\$Folder\DoIt & 'I:\SMS_DP$\sms\Tools\ExtractContent.exe' /P:I:\PrestageContent\$Folder\DoIt /F & Move-Item

Reset Inventory on SCCM client if over 7 days since report

Here is a little script that is a combination of several different pieces I found around the web. Basically it will check a machine and get the last HW & SW inventory dates. Then if those dates are over 7 days it will reset the inventory and trigger a new inventory to occur. Like I said nothing fancy, this script does require admin privs to run. However one could modify it to use the control panel com objects to call the built in inventory cycles like you would through the Configuration Manager control panel dialog. $inventoryQuery = "Select InventoryActionID, LastCycleStartedDate, LastReportDate from InventoryActionStatus" $inventoryResult = get-wmiobject -query $inventoryQuery -namespace "root\ccm\Invagt" $HWdate = $null $SWdate = $null $HWold = $true $SWold = $true ForEach ($iResult in $inventoryResult) {     $inventoryType = [convert]::ToInt32(($iResult.InventoryActionID).substring(35,2), 10)     switch ($inventoryType)     {         1 {

PS Script to convert a PS1 into a HTA that creates and executes a PS1

For one of my earlier posts I made a comment about creating a ps1 that is generated by a hta file and executed. Here is my shortcut script that I use to make the process a lot easier. Also the resulting hta file executes the powershell script in a non admin session and in the native OS architecture. So if you are running a 64bit OS it will make sure to run the 64bit Powershell even though the hta is running in 32bit mode. $a = Get-Content "c:\temp\original.ps1" $b = "c:\temp\original.hta" "<head>"| Out-File -FilePath $b "<title>Application Installation Helper Triggering Script- `${number}</title>"| Out-File -FilePath $b -Append "<HTA:APPLICATION "| Out-File -FilePath $b -Append "APPLICATIONNAME=""Application Triggering Script"""| Out-File -FilePath $b -Append "SCROLL=""yes"""| Out-File -FilePath $b -Append "SINGLEINSTANCE=""yes"&

Updating SCCM Application OS Requirement Rules

As many of you are aware Windows 10 was released, you also know this means that there is a new OS type in the selection dialog. However this also means that if you use OS requirements on your applications you have to go update them to add in Windows 10. Which lets face it, if you have a thousand or so apps, you really don't want to do this all by hand. Since I was faced with this dilemma  I decided to try scripting it. I discovered that it is not as easy as one would expect. After lots of searching and even some help from a friendly PFE. We were able to create something that would get the job accomplished. That being said here are the useful portions of the script that I hope will help you create one of your own that will meet your needs. I will warn you this is not pretty and the full script triggered some crosseye results from my teammates. Yes this is a very long and mostly code post. # Load SCCM Assemblies function Import-SCCMAssemblies { [CmdletBinding()]     param