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
Share

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

Share

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
Share

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.

Share

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

Share