Monthly Archives: April 2015

Connect-Mstsc – New version in TechNet Script Gallery

My Connect-Mstsc function was overdue for an update and I took the opportunity to add some additional feature to Connect-Mstsc as well. The purpose of this function is to start an RDP session with the specified user name and password. This functionality is not included in the mstsc.exe tool, which is why I wrote this script. The script is available for download in the TechNet script library: Connect-Mstsc.

This script accepts many parameters but two things need to be present, the ComputerName and either the combination of a User and a Password or a Credential object which will be used to authenticate the user against the remote system.

A simple example of how to use this function is as follows:

.EXAMPLE 
Connect-Mstsc -ComputerName server01 -User contoso\jaapbrasser -Password supersecretpw

Description 
----------- 
A remote desktop session to server01 will be created using the credentials of  contoso\jaapbrasser

Alternatively the -Credential parameter can be used to connect to a remote host:

.EXAMPLE
Connect-Mstsc -ComputerName 192.168.1.10 -Credential $Cred

Description 
----------- 
A RDP session to the system at 192.168.1.10 will be created using the credentials in   the $cred variable

The complete function is available in the TechNet Script Library. To view this script or to participate in the discussions about this script either comment here or in the TechNet Script Gallery. Because some of the new functionality, specifically the parameter sets and support for common parameter, the latest version of Connect-Mstsc is not compatible with PowerShell 2.0. To remedy this problem I have uploaded a PowerShell 2.0 compatible version as well.

TechNet Script Library
My entries in TechNet Script Gallery
Connect-Mstsc
Connect-Mstsc (PowerShell 2.0)
Share

Active Directory Friday: Use the ANR filter for LDAP Queries

ANR or Ambiguous Name Resolution is used to query for objects in Active Directory if the exact identity of an object is not known. A query containing Ambigious Name Resolution will query for all the attributes for example, Given Name, Sur Name, Display Name and samaccountname. For Windows Server 2008 and later versions this is the full list of ANR Attributes included in the search results:

For a full list of all the attributes that are queried please refer to the following TechNet article: ANR Attributes.

  • Display-Name
  • Given-Name
  • Physical-Delivery-Office-Name
  • Proxy-Addresses
  • RDN
  • SAM-Account-Name
  • Surname
  • Legacy-Exchange-DN
  • ms-DS-Additional-Sam-Account-Name
  • ms-DS-Phonetic-Company-Name
  • ms-DS-Phonetic-Department
  • ms-DS-Phonetic-Display-Name
  • ms-DS-Phonetic-First-Name
  • ms-DS-Phonetic-Last-Name

For a full list of all the attributes that are queried please refer to the following TechNet article: ANR Attributes.

An ANR query is useful in a number of scenarios, for example when relying on user input in your script. In this case querying against a samaccountname might fail if the spelling does not match the samaccountname. Similarly an export from a different department or database might be close to what is stored in Active Directory but not an exact match, again this is somewhere where an ANR query might be useful. Something that should be kept in mind is that this is a relatively expensive query and therefore should be avoided when it is not required. In this article we will discuss how to create an ANR filter and what happens exactly in such a query.

In the next example we will be using Get-ADUser cmdlet, which is part of the ActiveDirectory module, in combination with the LDAPFilter parameter in order to execute our query:

1
Get-ADUser -LDAPFilter '(anr=Jaap Brasser)'

This will query against all the attributes in the list as ‘Jaap Brasser*’ and two additionally queries: ‘GivenName=Jaap*’ and ‘SurName=Brasser*’ as well as ‘GivenName=Brasser*’ and ‘SurName=Jaap*’. As a result more than one result might be returned, as different attributes of a user account might overlap or are not unique to a single user account. This is the downside of this method of querying.

In the following example I will use the [adsisearcher] type accelerator to execute the same query:

1
([adsisearcher]'(anr=Jaap Brasser)').FindAll()

Alternatively the DirectorySearcher object can be manually created to execute a query:

$ADSearcher = New-Object DirectoryServices.DirectorySearcher -Property @{
 Filter = '(anr=Jaap Brasser)'
 PageSize = 100
}
$ADSearcher.FindAll()

For more information on this Ambiguous Name Resolution (ANR) have a look at the following resources:

Ambiguous Name Resolution
MSDN Ambiguous Name Resolution
ANR Attributes
KB Ambiguous Name Resolution for LDAP in Windows 2000
Share

QuickTip: Read single key press using [System.Console] class

When building an interactive script capturing a single key press might be necessary. In the previous article, QuickTip: Read single key press from PowerShell console, I showed how this is possible using the $host variable. In this article I will show how to read a key press using the [System.Console] class and in particular the ReadKey method.

The following example uses ReadKey with a single argument, $true, to ensure that the result of the function is not output to the console. Omitting $true or passing on $false as an argument will result in the output being displayed in the console as well as stored in the variable. Have a look at the example here:

$KeyPress = [System.Console]::ReadKey($true)

Similarly to the $host object ReadKey method not only the key itself but also the modifiers are passed on to the console. Here is the result of this method:

PS> $KeyPress
 
KeyChar      Key      Modifiers
-------      ---      ---------
      J        J          Shift

The modifiers are slightly different from what the $host object output. To have a look at the possible values we dig a bit further into the object stored in $KeyPress:

PS> $KeyPress.Modifiers.GetType()
 
IsPublic      IsSerial                Name           BaseType
--------      --------                ----           --------
True              True    ConsoleModifiers        System.Enum
 
PS> [Enum]::GetNames([System.ConsoleModifiers])
Alt
Shift
Control

For more information about the System.Console class have a look at its MSDN entry: Console Class

Share

New article on PowerShell Magazine: Save untitled tabs in PowerShell ISE to clipboard

When I am working in the PowerShell ISE I often have many open untitled tabs open. In order to bring some order to the chaos I wrote a small function to save all untitled tabs to the clipboard so I could paste it somewhere else. The full article  is available on PowerShell Magazine : Save untitled tabs in PowerShell ISE to clipboard

After posting this tip, I noticed that Richard Diphoorn posted a nice addition to this tip on his blog. He uses the Send-MailMessage cmdlet to send the untitled tabs by email, to OneNote for example. His post is available here: Send Unsaved Untitled PowerShell ISE tabs to E-Mail

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: Save untitled tabs in PowerShell ISE to clipboard
PowerShell Magazine
External Articles
Quantica: Send Unsaved Untitled PowerShell ISE tabs to E-Mail
Share

QuickTip: Read single key press from PowerShell console

When building an interactive script capturing a single key press might be necessary. This can be done by using the $host variable, specifically the ReadKey method. It is important to note that this method is only available in the PowerShell console this does not work in the PowerShell Integrated Scripting Environment (ISE).

A simple example: You might require your script to ask for Yes / No, using the Read-Host would allow the user to type in more than one character and the enter key would have to be pressed. In this scenario the ReadKey method is can be preferably, because it registers a single key press:

$KeyPress = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")

Now if we were to display the contents of the $KeyPress variable, we can see the following information:

PS> $KeyPress
 
VirtualKeyCode      Character      ControlKeyState      KeyDown
--------------      ---------      ---------------      -------
            89              y            NumLockOn         True

So the information contained that is captured by  this method not only contains the character, but also the type of key press as well as which additional ‘Control Keys’ were pressed. Control keys for example are the Numlock and Capslock status on your keyboard as well as Alt, Win and Ctrl keys. The control keys are part of the ControlKeyStates enumeration which can be enumerated using the [Enum] Class as shown in the following example:

PS> [Enum]::GetNames([System.Management.Automation.Host.ControlKeyStates])
RightAltPressed
LeftAltPressed
RightCtrlPressed
LeftCtrlPressed
ShiftPressed
NumLockOn
ScrollLockOn
CapsLockOn
EnhancedKey

For more information about using the GetNames method of the [System.Enum] class, please refer to my previous article: QuickTip: Enumerate objects with [System.Enum] class.

For example, if the goal is to construct a simple Y/N question using what we’ve learned so far can be placed in a while-loop:

$KeyOption = 'Y','N'
while ($KeyOption -notcontains $KeyPress.Character) {
 $KeyPress = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
}

And that how a single key press can be caught in a variable, adding in a switch or if-elseif-else statement will allow for action based on the key that has been pressed. Next week I will discuss an alternative to using the $host object for this purpose, stay tuned!

Share