Monthly Archives: June 2015

Quicktip: Use Windows Defender to scan a file or folder

As I was experimenting with the new PowerShell 5.0 cmdlets for Windows Defender I noticed that there is no parameter for starting a custom scan. As a workaround I used the mpcmdrun.exe tool to initiate the scan. For example the following code will execute a custom scan on C:\Temp:

1
& "$($env:programfiles)\Windows Defender\mpcmdrun.exe" -Scan -ScanType 3 -File 'C:\Temp'

MPCMDRun

This allows for scanning a custom folder, and the results will be displayed to the console. The results are also logged in the Windows Defender Operational log, if logging for Windows Defender has not been disabled. Using the Get-WinEvent cmdlet we can get this information from the eventlog.

1
2
Get-WinEvent -LogName 'Microsoft-Windows-Windows Defender/Operational' |
Select-Object -First 2 -ExpandProperty Message

MPCMDRun-EventLog

For more information on this topic have a look at the following resources:

Windows Defender
Security-Malware-Windows-Defender
Run (and Automate) Windows Defender from the Command Line

Quicktip: Create an object that refers to its own properties

Recently I received the question the /r/PowerShell community if it was possible to create an object that refers to its own properties when it is created. The user specified that they would prefer to create this as a one-liner.

Using the Add-Member cmdlet in combination with the -Passthru parameter this is quite simple to do, for example:

1
2
3
$Object = New-Object PSObject -property @{
    Property1 = 'Hello World'
} | Add-Member ScriptProperty GetProperty1 {$This.Property1} -PassThru

To make this slightly more interesting it is also possible to manipulate this object by using the manipulating the property. In the following example a property ‘Today’ is created and the script property uses this property to calculate the next week. For example:

1
2
3
$Object = New-Object PSObject -Property @{
        Today = (Get-Date).Date
} | Add-Member ScriptProperty NextWeek {($This.Today).AddDays(7)} -PassThru

ScriptPropertyNextWeek

It is also possible to create a ScriptMethod that uses the previously defined property, in the next example I create a ScriptMethod that can add or substract a week from the Today property:

1
2
3
4
$Object = New-Object PSObject -Property @{
        Today = (Get-Date).Date
} | Add-Member ScriptProperty NextWeek {($This.Today).AddDays(7)} -PassThru |
Add-Member ScriptMethod AddWeeks {param([int]$Week) $This.Today.AddDays($Week*7)} -PassThru

ScriptMethodAddWeeks

Search for files using WMI

Retrieving information about a remote Filesystem is possible in a number of methods, in this article I will focus on accessing a remote Filesystem using the Win32_Directory class in combination with Get-CimInstance. This can be useful in scenarios where you are not permitted by firewall or by other restrictions to use the Get-ChildItem cmdlet.

For instance, if we would like to gather the files stored in the root of the C-drive, this includes the hidden and system files, the following code can be used:

1
Get-CimInstance -Query "ASSOCIATORS OF {Win32_Directory.Name='C:\'} Where ResultClass = CIM_DataFile"

This same command can also be executed using the legacy cmdlet Get-WmiObject, some of the advantages of the Get-CimInstance cmdlet is that it will convert the WMI datetime objects to human readable PowerShell datatime objects. Also Get-CimInstance utilizes PowerShell Remoting which greatly simplifies queries against multiple systems simultaneously. The following code will generate a similar result to the previous code while using Get-WmiObject:

1
Get-WmiObject -Query "ASSOCIATORS OF {Win32_Directory.Name='C:\'} Where ResultClass = CIM_DataFile"

By using the Get-Member cmdlet an overview of all properties of the objects returned by this query can be shown:

1
Get-CimInstance -Query "ASSOCIATORS OF {Win32_Directory.Name='C:\'} Where ResultClass = CIM_DataFile" | Get-Member

To get a better overview the Select-Object object can be used to select some common properties:

1
2
Get-CimInstance -Query "ASSOCIATORS OF {Win32_Directory.Name='C:\'} Where ResultClass = CIM_DataFile" |
Select-Object -Property Name,CreationDate,FileSize,FileType

Win32_Directory-C-Root

It is also possible to get a list of folders contained, in the following example I will filter out only the CIM_Directory class instead of the CIM_DataFile type which results in only the folders related to the C:\Users folders to be displayed. This includes the Root folder C:\. The code is as follows:

1
2
Get-CimInstance -Query "ASSOCIATORS OF {Win32_Directory.Name='C:\Users'} Where ResultClass = CIM_Directory" |
Select-Object Name,LastModified,Path,Caption

Win32_Directory-C-Users

It is also possible to use the CIM_DataFile class directly to search the entire Filesystem for a file or folder matching the query. For example the following Query returns all ost files found on a system:

1
Get-CimInstance -Query "Select * from CIM_DataFile Where Extension = 'ost'"

A more complicated query could be to retrieve all ntuser.dat files on the local C: drive:

1
2
Get-CimInstance -Query "Select * from CIM_DataFile Where ((Drive = 'C:') AND (FileName = 'ntuser') AND (Extension = 'dat'))" |
Select Name

I hope this article was able to highlight some of the capabilities of these WMI classes and the Get-CimInstance cmdlet. I would like to remind you that all the code in this article could also be executed using the Get-WmiObject cmdlet, as the query strings are identical.

Links to the related WMI Classes
Win32_Directory Class
CIM_DataFile Class
CIM_Directory Class

QuickTip: Pin PowerShell to the Taskbar

When you are working with PowerShell in your daily work it might be worth considering pinning PowerShell to the taskbar. By doing this you have easy access using either the the mouse of the keyboard hotkeys.

PinPowerShell

By placing PowerShell in the first location on the taskbar you will have the following hotkeys available:

Description of action Key Combination
Open new (non-administrative) PowerShell console if not open already, otherwise cycle through open consoles <WIN> 1
Open new Administrative PowerShell console if not open already, otherwise cycle through open consoles <CTRL> <SHIFT><WIN> 1
Open new (non-administrative) PowerShell console even if a console is already open <WIN> <SHIFT> 1
Open the context menu, allows for opening:

  • PowerShell as Administrator
  • PowerShell
  • ISE as Administrator
  • ISE
<WIN> <ALT> 1

Using the mouse you have the following, similar, options available to you. Similar to the keyboard combinations:

Description of action Mouse Combination
Open new (non-administrative) PowerShell console if not open already, otherwise cycle through open consoles Click
Open new (non-administrative) PowerShell console even if a console is already open <SHIFT> Click
Open new Administrative PowerShell console even if a console is already open <CTRL> <SHIFT> Click
Open the context menu, allows for opening:

  • PowerShell as Administrator
  • PowerShell
  • ISE as Administrator
  • ISE
RightClick

Using these key combinations allows you to access PowerShell faster and no mouse-clicking will be required anymore.

QuickTip: Select all links using Invoke-WebRequest

Today I was looking for a way to discover all links on my blog. Invoke-WebRequest returns a number of interesting properties, which can be listed by piping the output into the Get-Member cmdlet:

1
2
Invoke-WebRequest -Uri 'www.jaapbrasser.com' |
Get-Member -MemberType Property

The output from the previous command shows that there is a property named ‘Links’, we will use this property to retrieve all the urls from a site. For example by executing the following code:

1
(Invoke-WebRequest -Uri 'www.jaapbrasser.com').Links.Href

To ensure that only the unique links are selected Select-Object -Unique can be used:

1
2
(Invoke-WebRequest -Uri 'www.jaapbrasser.com').Links.Href |
Select-Object -Unique

Invoke-WebRequest

Open Master Control Panel using PowerShell

This easter-egg or hidden control panel can be accessed by referencing its GUID. The Master Control panel is also known as GodMode, and has been referenced so often that it even has its own Wikipedia page now.

GodMode

It works by using a special GUID that gives access to almost all administrative tasks that are possible on a Windows system from a single window. Opening a control panel item by referencing a GUID is something that is supported by Microsoft. For example opening the ‘Mouse Properties’ control panel app can be done as shown in the next example:

1
explorer.exe --% shell:::{6C8EEC18-8D75-41B2-A177-8831D59D2D50}

The –% is used to escape any characters that come after it, this is done to ensure the brackets are not processed as a script block. This alternative notation achieves the same result:

1
explorer.exe shell:::`{6C8EEC18-8D75-41B2-A177-8831D59D2D50`}

Now if we would like to open the Master Control Panel, the following code can be executed:

1
explorer.exe --% shell:::{ED7BA470-8E54-465E-825C-99712043E01C}

It is also possible to create a special folder to be able to open this folder straight from your desk, the next code sample will create this folder for you:

1
2
3
'GodMode.{ED7BA470-8E54-465E-825C-99712043E01C}' | ForEach-Object {
    New-Item -ItemType Directory -Path (Join-Path $env:userprofile\desktop $_)
}

For more information about GUID and the related articles or about the Master Control Panel or GodMode have a look at the following links:

Master Control Panel
Canonical Names of Control Panel Items
Windows Master Control Panel shortcut

New article on PowerShell Magazine: Get last login date for local account

LastLogon

Two weeks ago I wrote Get-LocalLastLogonTime and blogged about this. In this script I use the [adsi] type accelerator in combination with the WinNT provider to retrieve the LastLogin property of a user account. I wrote a short article on this for PowerShell Magazine : Get last login date for local account

1
([ADSI]"WinNT://computer/jaapbrasser").lastlogin

For more articles like this, have a look at the External Articles section of my blog, it contains all the articles I have posted on external sources such as PowerShell Magazine.

Links in this Article
PSTip: Get last login date for local account
PowerShell Magazine
External Articles
My entries in TechNet Script Gallery
Get-LocalLastLogonTime