Monthly Archive


Putting user information into computer description

I was recently asked how to add user information – specifically first and last name – into computer description in Active Directory.

First get your user

$user = Get-ADUser -Identity FredBrown


Then add the information to the computer’s description

Set-ADComputer -Identity W10ProIp -Description "Used by $($user.Givenname) $($user.Surname)"


You need to use the subexpression – $() – syntax to resolve the values rather than getting references to the $user object.


Then test the description has been set

Get-ADComputer -Identity W10ProIp -Properties Description


If it was me I’d add the samAccountName or other unique identifier as name isn’t sufficient to uniquely identify the user

Install-Module in PowerShell v6.2 RC 1

Further to my last post it appears that Install-Module in PowerShell v6.2 RC1 DOESN’T follow the rules. In an elevated session if the scope parameter ISN’T used it will install to $home\Documents\PowerShell\Modules


The default appears to be CurrentUser regardless.


You have to use -Scope AllUsers if you want it to install in C:\Program Files\PowerShell\Modules

Install-Module Scope parameter

Be aware of the Scope parameter when using Install-Module. The following rules apply:

Allusers scope installs to $env:ProgramFiles\PowerShell\Modules

CurrentUser scope installs to $home\Documents\PowerShell\Modules

NoScope defined:

- - For an elevated PowerShell session, Scope defaults to AllUsers

- - For non-elevated PowerShell sessions in PowerShellGet versions 2.0.0 and above, the Scope is CurrentUser

- - For non-elevated PowerShell sessions in PowerShellGet versions 1.6.7 and earlier, Scope is undefined, and Install-Module fails


PowerShell v6.2 RC 1 uses PowerShellGet 2.0.4 and PowerShell v6.1.3 uses version 1.6.7. You’ll see different behavior depending on PowerShell version so the advice is to use the Scope parameter to ensure the module goes where you intend.


I usually want my modules in Program files (Allusers) rather than my documents folder (CurrentUser).


The lesson seems to be to use the Scope parameter rather than relying on defaults


The release of PowerShell v6.2 release candidate 1 brings more experimental features including PSTempDrive.


You can view the currently available experimental features using get-ExperimentalFeature. You’ll find a total of four:



Install PSTempDrive using

Enable-ExperimentalFeature –Name PSTempDrive


Restart PowerShell after enabling the feature.

Get-PSDrive will show a new drive named Temp. The root of the drive is set by the path in your TEMP environmental variable.


You can use and access the TEMP drive like any other drive set by PowerShell.


The TEMP drive follows the pattern of other drives created from a path on an existing drive using the filesystem provider in that the used and free space figures reflect the situation for the whole volume not the individual drives. The free space is OK like this as theoretically you could consume the whole of the available space on your new drive but the used space should reflect reality. The C: drive used space should be for the whole volume but the TEMP: drive should only show the space used in your TEMP folder etc.


If you want to remove the experimental feature – use Disable-ExperimentalFeature and restart PowerShell.


Not wholly convinced of the need for this particular feature but it gives marginally easier access to the TEMP folder.


Remember that experimental features are just that – experimental – and could be modified or even removed in a later version of PowerShell

PowerShell v6.2 release candidate 1

PowerShell v6.2 release candidate 1 is available -


The only breaking change is to how Join-String works in a non-pipeline scenario.  That shouldn’t be a big issue as Join-String is new to v6.2.


The security fixes from v6.1..3 have been incorporated in the release candidate.


Experimental features gets a couple of new options round creating a TEMP:\ drive and suggestions given when a command isn’t found.

PowerShell interviews

Following my last post about sample questions for PowerShell interviews that I’d stumbled across I’ve been asked what sort of questions I’d ask – given my statement that many of the question sets were out of date.


I’ve thought about it and decided I’ll run an occasional series of questions and the information I’d expect.


Before I start that I’ve thought some more around the whole issue of PowerShell interviews and there are some things to think about before jumping into performing an interview.


The most important thing is what are you interviewing for. What exactly does the role entail? There are a number of possibilities:


You want a PowerShell developer – the person will spend all of their time writing and maintaining code. Requirements and and specifications will be given to them. for this sort of role you’ll need to be mixing developer technique questions in with the powershelll questions.


You want someone to automate your administrative processes. Again development techniques ae going to feature alongside PowerShell questions. Ideally, you’d also want some one who would question the processes because automating what you have now is necessarily the best thing. I can remember being asked to generate a report about some products when I worked for a financial services organisation. Easy enough to do. I then asked 1 question – what was the report used for. It turned out that the data on the report was keyed into another system. The job then became extract data from system a and feed into system b and produce a report of what happened. That single question saved the users a bunch of time, effort and reduced errors from the re-keying of data.


You want an administrator who can also automate the administration of some or all of your environment. At this point you’re looking for someone who can administer X (or a bunch of Xs) and write PowerShell code that’ll make that job easier. You need to ensure that the person actually understand the system[s] as well as PowerShell.


Once you know the sort of person you want its time to think about the questions to ask. I’m going to assume that any other questions and just concentrate on questions about PowerShell from a theoretical and practical perspective. If you can sit the candidate down and make them write some code for you – but we’ll get to that another time.

PowerShell interview questions

For some bizarre reason I ended up looking at various sets of PowerShell interview questions and answers.


For the most part they scared me – due to their outdated nature.


Many, if not most, of the question sets hadn’t been brought up to date for PowerShell v5.1 and very few even mentioned v6.x. The remoting and CIM answers were often misleading.


And that’s just what I picked up on a quick scan through.


Bottom line is that if you need to prepare for an interview and you’re going to get PowerShell questions then make sure that you actually know the subject and don’t rely on dubious online sources.

Execution policy

PowerShell gives you a number of options regarding execution policy. You use one of the following options with Set-Execution policy:

Restricted – won’t run scripts or profiles. This is the default execution policy

Allsigned – only scripts (and profiles) signed with a trusted certificate can run. This includes anything you create on local machine.

RemoteSigned – Scripts (and profiles) on local drives will run. Scripts downloaded from Internet or from network drives are blocked

Unrestricted – anything runs though you are prompted before a downloaded unsigned script is run. This setting is what’s generally called a bad idea as its too permissive.

Bypass – everything runs without warnings or prompts. In most cases a worse idea than unrestricted

Undefined – removes currently assigned execution policy from the current scope though it won’t work if policy set by GPO


Just to add to the fun you have to think about the scope as well:

Process – only the current PowerShell process

CurrentUser –only the current user

LocalMachine – all users on the computer. This is the default setting.


I normally use RemoteSigned as it offers the best choice between ease of use and security. For an organisation that makes extensive use of PowerShell I’d recommend Allsigned with the code signing certificate only available to a small number of users who were responsible for performing quality assurance checks on the code.

Processing files with switch

The switch statement has a –file parameter that can be used to give the path to a file. The file is read one line at a time and processed through the switch statement. The example from last time can be used to demonstrate processing files with switch.


$fnum = 1

switch -file C:\test\Data.txt {
{$_ -like 'HOST*'} {
$file = "C:\test\outdata{0:00}.txt" -f $fnum
$fnum ++
Add-Content -Path $file -Value $_
default {Add-Content -Path $file -Value $_}


Initialize the counter as before. Use switch with the –file parameter to read the file. If the line is like HOST* then its the start of a block so create a new file name, increment the counter and add the content to the file.


Otherwise use the switch’s default option just to write the content to the file. If the data is more complicated then introduce additional processing options and allow default to just write out the data to the file.


This option on switch isn’t used much from what I’ve seen but is worth considering as it can offer some performance gains over other approaches.

Splitting a file

Saw a question about splitting a file that had repeating data blocks.

Each block starts with HOST so the code to split becomes:

$fnum = 1

Get-Content -Path C:\test\Data.txt |
ForEach-Object -Process {
if ($_ -like 'HOST*') {
$file = "C:\test\outdata{0:00}.txt" -f $fnum
$fnum ++

Add-Content -Path $file -Value $_


Initialise a counter variable $fnum


Get the file content and for each line test if it starts with HOST. If so create a new file name by using the format operator to substitute $fnum into the file path. {0:00} means put $fnum into the filed and ensure that its 2 digits so outdata01.txt instead of outdata1.txt. Increment $fnum


Write the line to the file.