PowerShell for Windows Admins


December 17, 2014  10:00 AM

Selecting AD properties

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Active Directory, Powershell

Saw a question on the forums about selecting name properties using the Microsoft AD cmdlets.  By default Get-AdUser returns a limited subset of properties:

£> Get-ADUser -identity richard
DistinguishedName : CN=Richard,CN=Users,DC=Manticore,DC=org
Enabled           : True
GivenName         :
Name              : Richard
ObjectClass       : user
ObjectGUID        : 7c42be70-c6b2-401f-8296-46de9ee7446c
SamAccountName    : Richard
SID               : S-1-5-21-195014076-723736408-1406369008-1104
Surname           :
UserPrincipalName : Richard@Manticore.org

 

Given name = first name

 

if you want other properties you have to explicitly aske for them using the –Properties parameter. You can use a wildcard * but if you have a big AD that could be a lot of unrequired data you are pulling back. On the other hand if you want a lot of properties its often simpler to use the wildcard. As with most PowerShell related things there is no answer that is right all of the time.

 

The user asking the question wanted the first name, last name and department for all users in a given OU.  Use the OU as the –SearchBase.  The property you need to explicitly ask for is Department:

£> Get-ADUser -Filter *  -SearchBase ‘OU=Testing,DC=Manticore,DC=org’ -Properties Department | select GivenName, SurName, Department | fl *
GivenName  : Dave
SurName    : Green
Department : Testing

 

Selecting AD properties can be a little bit awkward if you forget that the default set is limited.  If in doubt of a property name – display them all for one user:

Get-ADUser -identity richard -Properties *

December 15, 2014  3:54 PM

WMI — identifying writable properties

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
CIM, Powershell, WMI

One common mistake I see is people trying to set the value of a read only property on a WMI class.  There isn’t a quick way to see if a property is writable. Get-CimClass can be used but you have to dig into the Qualifiers for each property.

 

You can use this function to determine the read\write settings on all of the properties of a WMI class

function get-cimreadwriteproperties {
[CmdletBinding()]
param (
[string]$classname
)

$props = @()

$class = Get-CimClass -ClassName $classname
$class.CimClassProperties |
foreach {
$prop = [ordered]@{
Name = $psitem.Name
Read = $false
Write = $false
}

$psitem |
select -ExpandProperty Qualifiers |
foreach {
if ($_.Name.ToLower() -eq ‘read’) {
$prop.Read = $true
}
if ($_.Name.ToLower() -eq ‘write’) {
$prop.Write = $true
}
}

$props += New-Object -TypeName PSObject -Property $prop
}

$props

}

 

Take the class name as a parameter and use Get-CimClass. Iterate through the properties and foreach create an output object. Test each qualifier to determine if read or write and set out to true. Add to array and output.

 

The output looks like this

 

£> get-cimreadwriteproperties -classname Win32_bios | ft -AutoSize

Name                  Read Write
—-                  —- —–
Caption               True False
Description           True False
InstallDate           True False
Name                  True False
Status                True False
BuildNumber           True False

etc

 

 

£> get-cimreadwriteproperties -classname Win32_LogicalDisk | ft -AutoSize

Name                          Read Write
—-                          —- —–
Caption                       True False
Description                   True False
InstallDate                   True False
<truncated>

ErrorMethodology              True False
NumberOfBlocks               False False
Purpose                       True False
<truncated>
VolumeDirty                   True False
VolumeName                    True  True
VolumeSerialNumber            True False


December 12, 2014  2:10 PM

Delivering PowerShell code

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

Do you have a need to deliver PowerShell code to multiple machines. I do. I have a dev environment plus test and production environments. I need to move code from dev through test and production.

One way to do this is to create all of your code as modules and use the PowerShell 5.0 feature – PowerShellGet.

This feature enables you to install modules from a central repository. The default is a public, cloud based, repository but you can create your own.

I’m going to investigate the possibilities in a series of posts


December 10, 2014  1:40 PM

Learning PowerShell

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

I’ve been thinking about how people learn PowerShell through watching some people at work who are learning it and watching the questions on the forums – many of which start off “I’m new to PowerShell and…”

There seems to be two broad approaches:

Option 1 is to get some training. This could be a formal course, video training or the excellent Learn PowerShell in a Month of Lunches book. Then find problems to solve.

Option 2 takes the opposite approach and finds the problems to solve then starts figuring out how to use PowerShell to solve them.

Which route you take depends on a number of things:

how you like to learn

the environment you work in – can you actually find time to start using PowerShell, and approval,

the technologies you work with

The options above both assume that scripting is your end goal. I’d suggest one other approach that may help. Use the cmdlets you have directly from the command line.  You can accomplish a lot by piping a few cmdlets together. This gets you used to working with cmdlets and the PowerShell language.

Keep it Simple and start small. You’ll soon start progressing.


December 9, 2014  2:54 PM

What Formatting cmdlets do to your data

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

I have seen an increasing number of questions recently where the answer has been to remove Format-Table from the pipeline. As an example consider the names of the processes running on your machine

Get-Process -Name calc | Stop-Process

works because you are piping the selected object into the Stop-Process cmdlet.

Now think about this

Get-Process -Name calc | select Name | Stop-Process

a bit more long winded (the select isn’t necessary) but the resultant object hitting Stop-Process identifies a process by name which is all Stop-Process needs to work.

As a way to approach the reason for the first sentence in the post is there any difference between these two statements?

Get-Process -Name calc

Get-Process -Name calc | Format-Table

The output to screen looks identical. So  I should be able to do this:

Get-Process -Name calc | Format-Table | Stop-Process

What I get is a bunch of errors of the form:

Stop-Process : The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties do not match any of the parameters that take pipeline input.
At line:1 char:41
+ Get-Process -Name calc | Format-Table | Stop-Process
+                                         ~~~~~~~~~~~~
+ CategoryInfo          : InvalidArgument: (Microsoft.Power…FormatStartData:PSObject) [Stop-Process], ParameterB
indingException
+ FullyQualifiedErrorId : InputObjectNotBound,Microsoft.PowerShell.Commands.StopProcessCommand

The reason for this is simple.  The Format cmdlets destroy your pipeline and objects.  They take what they are given and output formatting directives. The only thing you can do with them is display them on screen (you can pipe to a text file but effectively the same thing)

If in doubt about what you’re dealing with at any time use Get-member

£> Get-Process | Get-Member

TypeName: System.Diagnostics.Process

£> Get-Process | select name | Get-Member

TypeName: Selected.System.Diagnostics.Process

Notice the slight change in that its now Selected.System.Diagnostics.Process instead of System.Diagnostics.Process

This only applies if you’re selecting a subset of properties. If you want the first N objects

£> Get-Process | select -First 5 | Get-Member

TypeName: System.Diagnostics.Process

You still have the original type.

However, lets look at formatting

£> Get-Process | Format-Table | Get-Member

TypeName: Microsoft.PowerShell.Commands.Internal.Format.FormatStartData

TypeName: Microsoft.PowerShell.Commands.Internal.Format.GroupStartData

TypeName: Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData

TypeName: Microsoft.PowerShell.Commands.Internal.Format.GroupEndData

TypeName: Microsoft.PowerShell.Commands.Internal.Format.FormatEndData

 

You get 5 different objects out – none of which have anything to do with your processes – apart from the values.

The Format cmdlets are designed to format your data for display. Thats all they do. Once your data hits the Format cmdlets that data can only be used fro display – nothing else. Put your Format cmdlets at the end of your pipeline and don’t attempt to do anything else with the data.


November 28, 2014  12:38 PM

Add a drop down to a Word document

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Microsoft Word 2013, Powershell

 

Its surprisingly easy to programatically add a drop down list to Word document

 

$Word = New-Object -Com Word.Application
$word.visible = $true
$template = “c:\test\template.docx”
$Doc = $Word.Documents.Open($template)
$Doc.Activate()

$cntrl = [Enum]::Parse([Microsoft.Office.Interop.Word.WdContentControlType], “wdContentControlDropdownList”)

$objCC = $doc.ContentControls.Add($cntrl)

$objCC.DropdownListEntries.Add(“PowerShell”)
$objCC.DropdownListEntries.Add(“Ruby”)
$objCC.DropdownListEntries.Add(“Perl”)

 

Create the COM object for Word and set visible.  Open a template (in this case a blank document) file and activate.

 

Set the type of control you want to add and define the possible entries.

 

It should be possible to set the default text but the method for doing that appears to be very awkward.  I’ll publish that if I work it out.


November 27, 2014  2:46 PM

The little changes that make a difference

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

Each version of PowerShell introduces a new headline feature – remoting, workflows, DSC, OneGet in version 2,3,4 and 5 respectively. While this can change the way we work there are also a host of little changes that come along that are often overlooked.

One example is a change to Get-ChildItem introduced in PowerShell 3.0.

Consider getting a directory listing:

Get-ChildItem -Path C:\Windows

This will give all subfolders and file in the given folder.

If you just wanted the files you had to do this:

Get-ChildItem -Path C:\Windows | where {$_.PSIsContainer}

If you want just the files you use:
Get-ChildItem -Path C:\Windows | where {-not $_.PSIsContainer}

or the slightly shorter but not as easy to read:
Get-ChildItem -Path C:\Windows | where {!$_.PSIsContainer}

The PSIsContainer property name is not intuitive and I rarely remember the name exactly and try ISPSContainer first or some other variant.

Two additional filtering parameters were added to Get-ChildItem

Get-ChildItem -Path C:\Windows –Directory

and
Get-ChildItem -Path C:\Windows -File

produce listings of folders and files respectively.

A small simple change that makes life easier.

There are a lot of small changes like this scattered through the later PowerShell versions – I’d recommend going through the release notes to track down the ones that will be useful to you.


November 26, 2014  1:53 PM

Persisting PowerShell Objects

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

I was asked recently about persisting PowerShell objects. The idea was to test a particular property on a semi-regular basis and save the object with the highest value for the property.  If the next test has a higher value it is saved and overwrites the existing object.

 

There are a number of ways to do this – if you are running the test very frequently then you could keep the object in memory as a variable. If you are testing fairly infrequently then you may want to persist the object to disk.  The CliXml cmdlets are good for this.

 

Start by creating a reference object:

Get-Process -Name powershell | Export-Clixml -Path proc1.xml

 

Then run some more tasks in PowerShell to increase the CPU usage. You can do this with any property that will change over time.  CPU is an easy example. You can then run your test. I used an instance of ISE to do the test so I didn’t alter the value by running the test.

 

$proc = Get-Process -Name powershell

Get-ChildItem -Path .\proc1.xml

$psp = Import-Clixml -Path .\proc1.xml

if ($proc.CPU -gt $psp.CPU){

$proc | Export-Clixml -Path proc1.xml

}

Get-ChildItem -Path .\proc1.xml

 

Get the current data and test the saved file. Import the saved file.  Test the CPU values and if the new value is higher save the object by overwriting the file.  Repeat as required.

 

The help files for Export-CliXml and Import-CliXml should be read.


November 25, 2014  2:17 PM

PowerShell Summit Europe 2015 – – topics to include

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

Are you planning on attending the PowerShell Summit Europe 2015.  If so what topics would you like to see covered. The Summit is deliberately pitched at a high level so you won’t find beginner level content.

If there’s a topic you’d like to be included in the agenda – leave a comment explaining what it is and why you think it would make a good Summit topic. No promises but we’ll see what we can do


November 24, 2014  2:05 PM

Call for Presentations for PowerShell Summit Europe 2015

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

The PowerShell Summit is the number one conference where PowerShell enthusiasts gather and learn from each other in fast-paced, knowledge packed presentations. PowerShell experts from all over the world including MVP’s, Guru’s, community leaders and PowerShell team members, will once again join together for a few days in Stockholm, Sweden to discuss and learn about maximizing PowerShell in the workplace. If you want to share your PowerShell expertise or story, then this is your official call to submit presentations for selection!

PowerShell Summit Europe 2015 will be held 14-16 September 2015 in Stockholm, Sweden.

Topic Areas – What we are looking for

We are looking for 45-minute presentations covering a wide aspect of PowerShell expertise. We have two main topic areas that may assist you in building an abstract.

PowerShell Internals – A deep look into the inside workings of PowerShell and practical solutions that are built from them. These presentations are typically more directed to the PowerShell development community that is building extensions and solutions relating to PowerShell.

PowerShell Features Deep Dive – These presentations are a deep look into configuring and working with PowerShell features and capabilities such as Remoting, Desired State Configuration and more. These presentations tend to be more IT Pro focused.

We are open to presentations across the entire ecosystem that has been built around PowerShell; so don’t hesitate to send an abstract for your particular area of expertise. This includes Microsoft platforms and products that have PowerShell-based management tools as well as 3rd parties such as VMware. New topics will be preferred over recycling of older topics – look to see what’s new in PowerShell 5.0 and use the questions on PowerShell.org to spot areas of confusion that could supply a good session for the Summit.

What kind of sessions get selected?

We’re looking for sessions that go beyond – often way beyond – “beginner.” If you want to see examples of the depth we’re looking for use the recordings on the PowerShell.org Youtube channel from the PowerShell Summit Europe 2014 as a guide. We look for an abstract that’s compelling and makes us salivate to see your session – so spend time writing a punchy abstract! We want sessions that offer real-world usability combined with “wow, nobody talks about THAT” awesomeness. If in doubt aim high. Remember, Summit sessions are recorded, so if you’ve previously presented a topic at a Summit, we’re less likely to choose it for another Summit. We want sessions that are challenging, and that ideally present things that simply aren’t explained or documented elsewhere. New modules, new techniques, and crazy approaches are all welcome. Discussion-format sessions are great, too, especially if you plan to turn them into a community deliverable (like a “best practices for writing DSC Resources” session that gets turned into a free e-guide later). Think community, deep dive, engaging, and amazing as keywords. We want attendees to finish each day with information leaking… just a little bit… out their eyeballs. Help us make it happen.

We do have some goals for speaker selection, too. We obviously have, and appreciate, the great involvement we get from the product team. We aim to have a certain number of sessions from well-known members of the community, simply because they’re well-known for a reason – they do a great job! But we also set aside slots for newcomers who’ve never presented before, or who’ve maybe only presented once or twice before – the audience will judge you on content not style. We want to create opportunities for more folks to become engaged and active in our community, and the Summit is a great way to do that.

We aren’t looking for soft-skills sessions, like “how to get a new user group running,” although contact us via email (summit@) if you’d like to do something like that as an extra evening thing after the main content wraps for the day.

Please note all sessions are to be delivered in English. Presenter will provide all equipment needed to deliver session(s), including a laptop or other computer. Presenter must be able to provide video by means of HDMI, DVI-D, or DisplayPort connectors – VGA is NOT supported. Presenter must be able to manually select an appropriate screen resolution for video output. Typically, 1024×768 or 1280×720 are preferred.

How to submit abstracts of presentations

Presentations will be 45-minutes in length and the submission should include the following:

Presentation Title

Presentation abstract – a description of the presentation and the topics covered. 250 words or less and suitable for marketing.

Go to http://eventmgr.azurewebsites.net/event/register/PSEU15/Europe%202015%20Member?preregister=1. This is the only valid URL for pre-registration. Provide your e-mail address, password, and full name. You’re creating a new account, even if you’ve attended past Summit events.

Do NOT attempt to register for the Summit as an attendee at this stage – we will be opening registration in late February 2015.

Click Abstracts

Click Submit Abstract

Provide a title and description; descriptions must be 50-250 words. Set the Status to “Ready to Review” when you are ready to send your session to us for consideration.

To return to the site at a later time, go to http://eventmgr.azurewebsites.net/event/login/PSEU15. Click Log In. You can then re-visit Abstracts.

Note that you must set your abstract status to Ready for Review or we won’t see it. If you leave it in Pending, it won’t be considered.

You can submit multiple presentations in the same topic area or for different ones. Be aware that even though the session length is 45 minutes we prefer to have at least 10 minutes set aside for questions. Summit presentations are intense and intimate often with plenty of audience interaction. You must expect questions and discussions. This is not a “lecture to the audience” event. Also because of the session length, generally co-presenters are unnecessary, but that is not a requirement.

Presentation submission deadline – When you should send it by

Start sending your presentation submissions immediately! The selection committee will start selecting presentations as soon as they arrive so you don’t want to miss out. The last day we will accept presentation submissions will be Sunday 11 January 2015. This is a hard deadline.

When you will know you’ve been selected

The selection committee will start reviewing submissions immediately and begin the selection process. You will be informed if one or more of your presentations have been selected and sent a contract on or before Sunday 18 January 2015. You will need to return the signed contract by Wednesday 28 January 2015 otherwise another speaker may be offered the opportunity.

Speakers, with accepted sessions, will be given free admission to the event, including attendance at all official Summit activities. However, AWPP membership is not included. Speakers may not bring guests to the day sessions or evening events. We have a limited budget, and the number of speakers selected will be partially governed by that budget. Speakers are responsible for their own travel expenses, including hotel, airfare, and ground transportation.

The final agenda will be announced and posted on PowerShell.Org on, or about, Monday 2 February 2015.

We look forward to your submissions and your help in making PowerShell Summit Europe 2015 the most valuable IT/Dev conference of the year building on and surpassing the Europe 2014 Summit!


Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to: