Maintaining ConfigMgr (SCCM) Software Update Point and WSUS

Here is an EXCELLENT article on properly maintaining the ConfigMgr Software Update Point and WSUS, deleting old/superseded updates, performing  a defragmentation/re-indexing job on the WSUS database, as well as resolving  the following errors from theWindows Update agent :
OnSearchComplete – Failed to end search job. Error = 0x80244022. 
Scan failed with error = 0x8024402

Powershell Special Characters

Powershell has a plethora of special characters. Here is the most complete listing found to date

$ (dollar sign)
Declare/use a variable. Powershell has a number of built-in variables (thanks to Rein), such as $null, $true or $false. These are case insensitive and usually read-only, either explicitly (they will produce an error if you try to reassign them), or silently ignoring any updates.Example.

$abc = "123"

$_ (dollar underscore)

'THIS' token. Typically refers to the item inside a foreach loop.
Task: Print all items in a collection.

... | foreach { Write-Host $_ }

$$ (double dollar, two dollars)
Last token of last command. Does NOT refer to the whole command.

Write-Host "Hello, world!"
Hello, world!
Hello, world!

$^ (dollar sign + caret)
Thanks to Richard for accidentally finding this one.
First token of last command. Does NOT refer to the whole command.
Write-Host "Hello, world!"
Hello, world!
$? (dollar sign + question mark)
Many google searches were looking for this information, so I experimentally found what it does.
Returns True or False value indicating whether previous command ended with an error. For some reason it does not catch all errors, but most of the time it works.
Task 1: See if a powershell cmdlet exists in the system.
SomeCmdLet #does not exists
The term 'SomeCmdLet' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the
spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:15
+     SomeCmdLet <<<<  #does not exists
    + CategoryInfo          : ObjectNotFound: (SomeCmdLet:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException
False    #error occured - previous cmdlet (SomeCmdLet) was not found
True     #no errors returned by the previous command ($?)
Task 2: See if a WMI class exists in the system
gwmi win32_processo -ErrorAction SilentlyContinue   #intentional error, win32_processor is the right one
[type] (square bracket + type name + square bracket)
Credit goes to Michael for suggesting to add this.
Aside from type casting, it can be used to specify strongly typed variables, particularly useful with arrays.
Yes, Powershell is pretty good as inferring the type of variables based on the actual values, but just in case you want to limit script input.
Example 1.
$a = 1,2,3 #declare an array of object containing integer values
$a = $a + 'hello'; #adding a string value at the end of object array is perfectly fine
Output 1.
Example 2.
[int[]]$a = 1,2,3 #declare an array of integer
$a = $a + 'hello'; #triggers an error, cannot add string to an array of integer
Output 2.
Cannot convert value "hello" to type "System.Int32". Error: "Input string was not in a correct format."
$() (dollar sign + round brackets)
Thanks to Kevin for a suggestion to add this one.
Sub-expression operator for double-quoted strings. Whatever is in the brackets should be evaluated first.
$name = "Kevin";
"Hello, $name, there are $($name.length) characters in your name"
Hello, Kevin, there are 5 characters in your name
It can be used with any expression, so this will also work:
"There are $(2+3) characters in your name"

${} (dollar sign + curly brackets)
Thanks to Remco for a hint about it.
Declare or use a variable with non-standard characters in it, a more generalized syntax to $variableName. It adds support for punctuation or non-English characters.
${,,,} = 5

| (pipeline)
Catch output of the command and pass it to another command.
Task: Get list of processes and select top 3 items.
Get-Process | Select-Object -first 3

% (percentage)
1. Shortcut to foreach.
Task: Print all items in a collection.
... | % { Write-Host $_ }
2. Remainder of division, same as Mod in VB.
5 % 2
. (single dot) Credit goes to Marc for asking to add this one.1. Include external powershell file as part of your script (also known as dot sourcing). Any functions or variables will become available in the current scope.
#line 1 of your script
. ./script.ps1 #include from current directory
#line 2
#use function or variable from script.ps1
2. Accessing a non-static member of the class, or to fully qualify a namespace, same as in C# or another object oriented language.
$a = "Hello"; #a is now a .NET string
$a.Substring(1) #prints "ello"
As a reminder, to access static members you should use double colon (this case is described further on this page):

.. (double dot)
Specify a range.
Task: Print numbers 1 through 5 without a foreach loop.


:: (double-colon)
Thanks to Darrell for asking about this one.
Reference static member of a class. The class name must be enclosed in square brackets.
Task: Compare two strings.
[string]::Equals("a", "b")

+ (plus sign)
Thanks to Cody for pointing at this feature of Powershell.
Aside from its natural use, i.e. addition of two arguments, you can also use a plus sign to reference a public nested class.
For official reference, see here. Thanks to David Brabant for help in figuring this out.

+= (plus equals)
Thanks to Brian G.
Increments value on the left by the amount on the right (and stores result). For strings it means concatenation.
Very well known to C# developers
, so not strictly a Powershell feature.
In Powershell, however, this operator has a special use - you can add elements to arrays.
Mostly syntactic sugar, the array is still recreated behind the scenes, so just to save a few characters.
$b = 1         #initialize a variable
$b += 2        #add 2
$b             #output 3 (1 + 2)

$a = @(1,2,3)  #initialize array with 3 elements
$a += 4        #add element number 4
$a             #output 4 elements


--% (double minus + percentage sign)
Thanks to Michael for suggesting to add it.
Available since Powershell v3.0 (links to blogs @ MSDN), it stops Powershell style of parsing and allows to feed commands with special characters, without them being treated as such.
Example 1 (using --% magic).
Write-Host --% %USERNAME%,this=$something{weird}
Output 1 (using --%).
--% %USERNAME%,this=$something{weird}
Example 2 (same thing, not using --% magic).
Write-Host %USERNAME%,this=$something{weird}
Output 2 (not using --%).
%USERNAME% this= weird

! (exclamation mark)Thanks to Leo for asking about this one. 
Shortcut to -not.
$a = $null;
if(!$a) { Write-Host '$a is null' }
$a is null

? (question mark)Output all items that conform with condition (shortcut to where). Shortcut to the following: 
foreach { if (...) {return ... } }
Task: Print all odd numbers between 1 and 5 (inclusive):
1..5 | ? { $_ % 2 }

` (backtick)
1. Continue command on the next line.
Write-Host `
"Hello, world!"
Hello, world!
2. Include a special symbol into a string. Available options:`$ - include a dollar symbol in your string. If you don't escape it, Powershell will assume you are trying to embed a variable.
`0 - Null. My preference is using $null instead.`a - Alert. Yes, it does make sound, and you can use multiple for multiple beeps.
`b - Backspace
`f - form feed - only affects printed documents.`n - New line`r - Carriage return`t - Horizontal tab`v - Vertical tab - only affects printed documents.
`' - Single quote - I prefer using double quotes when I need to escape a single one, since I don't need any escaping in this case.`" - Double quote - you can use single quotes, and you don't need this symbol. My preference is use standard escaping instead, so 4 double quotes ("""") means a double quote.
Official article by Microsoft with full description on every token:

# (hash sign)
Single line comment.
#This is a commented line
#This is a second one

<# ... #> (left angle bracket / &lt + pound ... pound + right angle bracket / &gt)
Block/Multi-line comment.
<#This is
a commented

& (ampersand)
Execute string as command.
& "Get-Process"

@( ) (email-at + round brackets)Declare arrays.
Note: comma is used as a separator, in contrast to hash table declaration.
$a = @("One", "Two", "Three")

@{ } (email-at + curly brackets/braces)Declare hash tables. Powershell 2.0 introduced a new feature called parameter splatting, which is one of the nice uses for hash tables.
It allows you to supply dynamic values and number of arguments to an otherwise static call of the function (see Example 2 below). 
Note: semicolon is used as a separator, in contrast to array declaration.
Example 1 - Declare hash table and get item by key.
$a = @{"1" = "one";
       "2" = "two";
       "3" = "three"}
$a["2"] #prints "two" (without quotes)
Example 2 - Declare empty hash table, populate with arguments, and use parameter splatting.
$params = @{};
$params['class'] = 'Win32_DiskDrive';
$params['filter'] = 'size=256052966400'; #find a drive which is 256GB in size
Get-WmiObject @params
#identical to Get-WmiObject -Class 'Win32_DiskDrive' -Filter 'size=256052966400'

@' ... '@ (email-at + single quote ... single quote + email-at)Multi-line string literal without embedded variables.

@" ... "@ (email-at + double quote ... double quote + email-at)
Multi-line string literal with embedded variables.

0x (zero x + number)
Specify a number in hexadecimal form.
Note 1. You can use this notation to specify Unicode characters.
Note 2. You can embed Unicode characters into a string, combining this and $() notation (described prior on this page):
"Some Company $([char]0x00AE)"
Output (Powershell console will display ® as R, you can use PowerGUI Script Editor to properly see the result).
Some Company ®  


Getting Help on a Powershell Command:Get-Help

To obtain a list of help topics available in Powershell use the Get-Help command:

Get-Help *

Need help on a service?

Get-Help Get-Service

Need examples of the commandlet?

Get-Help Get-Service -Examples
(this command will work only if all help files for the cmdlet are installed on the computer. Otherwise Powershell will prompt to initiate Update-Help.

To access help for Powershell Commands online:

Get-Help commandlet-name Online

Get-Help Get-Service Online

a browser windows will open with the help

Getting Help on a Powershell Command: Get-Command

Get-Command can provide you with details on the Powershell commands available to you in a particular instance.

So if you know the Powershell command (Verb-Noun) that you are needing to use but struggling with the format or parameters, you can execute the following to get help with the command:

(Get-Command CommandName).parameters


If you are trying to get the parameters used for the New-CMDeviceCollection command using Powershell with Configuration Manager (SCCM), the get command would be:

(Get-Command New-CMDeviceCollection).parameters

If you want to know all the Powershell commands that start with S:
Get-Command S*

If you want to know what parameters are used with the Powershell command Suspend-Service
(Get-Command Suspend.Service).parameters

How to Export a user's mailbox from Exchange to PST

Open Exchange Management Shell

 Start – All Program – Microsoft Exchange server 2010 – Exchange Management Shell

 Enter the following command:
New-MailboxExportRequest -mailbox <user name> -filepath "\\ExchangeServerName\exchange_archive\Former_PSTs\<user name>.PST" –AcceptLargeDataLoss –BadItemLimit unlimited

Enter the following to check status of job:
Get-mailboxexportrequest -mailbox <>

Run the following command to remove the export requests:

Get-MailboxExportRequest | Remove-MailboxExportRequest

How to Configure Windows to Allow Run As Administrator for a MSI

When you need to install a program as an administrator, you can right click on the .exe file and select Run As Administrator, But Run As Administrator is not an available right click option for MSI packages.

Install As Administrator right click option can be configured by making a registry change to Windows 7/8/8.1/10.

  • Open Regedit
  • Navigate to the Registry Key: HKEY_CLASSES_ROOT\Msi.Package\shell
  • Right click on the Registry Key shell
  • Click NEW
  • Click KEY
  • A new sub-key is added under Shell with the default name New Key #1
  • Rename New Key #1 to Runas
  • In the right side pane, right click on Default Value
  • Click Modify
  • In the Edit String dialog box under Value Data, enter Install as &administrator
  • Click OK

  • Right click the Runas key 
  • Click NEW
  • Click KEY
  • A new sub-key is added under Runas
  • Rename the sub-key to Command
  • Click the Command subkey
  • In the right side pane, right click on Default Value
  • Click Modify
  • In the Edit String dialog box under Value Data, enter msiexec /i “%1”
  • Click OK

  • Close the Registry Editor

Now, when right clicking an MSI installation package file, an option Install as Administrator will be available.

How to Remediate Vulnerability “Microsoft Windows Unquoted Service Path Enumeration” (Nessus plugin ID 63155)

"Organizations can expect with certainty that at least some software that is used to support the business will have a vulnerability. The vulnerability may be a low risk and left alone, or the vulnerability may be a critical risk and need immediate attention. However, the impact of the vulnerability tends to be focused to one particular piece of software which may or may not be used widely in an organization.
A Windows system has many services, which are programs running in the background. These programs exist somewhere in the file system, for which the service manager uses the file path to find the program to then run the service. In some cases, there are breaks in the names of folders in the path to the program in the file system. For example, a program such as “myprogram.exe” can exist in the folder “c:\temp\My Folder\”. In Windows, a service can specifically can point to c:\temp\My Folder\myprogram.exe or it can enclose the absolute path in double quotes such as “c:\temp\My Folder\myprogram.exe”. The operating system will resolve the path to the program in either case and run the service. This is a design decision by Microsoft to run the service as previously described.
As the service can run in either configuration, there are no problems from a functionality or availability perspective. There are clear and concise rules Windows will follow, but will try to look for “myprogram.exe” in a folder path of “c:\temp\My” and then “c:\temp\My Folder”. The space is treated as an optional path to explore for that program. The attack scenario occurs when, by happenstance or malicious intent, there was a folder of “c:\temp\My” with an innocuous or malicious program also called “myprogram.exe”, which would be run first by the service manager.
As this complete scenario is a design decision by Microsoft and programs are not required to have double quotes, this scenario could potentially be exploited by attackers. When an organization uses Tenable SecurityCenter CV and Tenable Nessus, this scenario is identified with our solutions. An analyst can scan a network with Nessus using plugin ID 63155 to specifically identify services on systems using unquoted file paths. Once found, analysts can work with the appropriate personnel to remediate the issue with either vendor support or by manual intervention within the service manager.
This report provides a focused analysis of this issue across the organization. Analysts can use this to quickly determine which hosts and services are impacted with this vulnerability. Additional information, such as the impact across IP address ranges and the impact over time, is provided to the analyst to help determine how long this issue has persisted across the organization.
This report is available in the SecurityCenter Feed, a comprehensive collection of dashboards, reports, Assurance Report Cards, and assets. The report can be easily located in the SecurityCenter Feed under the category Discovery & Detection. The report requirements are:
  • SecurityCenter 5.4.0
  • Nessus 6.8.1
Tenable SecurityCenter Continuous View (CV) provides continuous network monitoring, vulnerability identification, and security monitoring. SecurityCenter is continuously updated with information about advanced threats and zero-day vulnerabilities, and new types of regulatory compliance configuration audit files. Tenable constantly analyzes information from our unique sensors, delivering continuous visibility and critical context, enabling decisive action that transforms your security program from reactive to proactive. Active scanning examines the devices on the systems, running processes and services, configuration settings and services, and additional vulnerabilities. Tenable enables powerful, yet non-disruptive, continuous monitoring of the organization to ensure accurate and up-to-date information is presented on existing vulnerabilities discovered within the network.
This report contains the following chapters:
  • Executive Summary: This chapter provides an overview of the Microsoft Windows unquoted service path vulnerability in the organization
  • Microsoft Windows Unquoted Service Path Vulnerability Details: This chapter provides a detailed view of the Microsoft Windows hosts affected with the unquoted service path vulnerability"

This script locates all services from HKLM\SYSTEM\CurrentControlSet\services, identifies paths with spaces and without the quotes and remediates by setting the quotes at the beginning and end of the path