Skip to main content

How to address Property Names with Spaces in them?

Things don’t always go as planned.  For example when my wife and I moved from Indiana to Arizona this spring.  We were planning on taking three days to drive the dogs from Indianapolis to Phoenix.  I was at the PowerShell Summit in Redmond and she was home finishing the packing.  I could tell by the way she was sounding on the phone that things were not going well so I jumped on an early flight to come home.  Well….I landed in Houston to find the plane was broken and no flights left to Indianapolis.  The airline was planning on getting me home around 2:30 PM the next day. Um,…no.  So I took a plane to Chicago that night and slept in the USO and got home at 10 AM to help my wife.  Sometimes you have to turn a challenge into an opportunity.

Sometimes you need to work with data that was never indented to be used with PowerShell.  This can present a challenge.  Those of you who have taken my PowerShell classes know that I frown on any variable that has a space in it.  Take a look at what you have to do to get a variable with a space in it to work.

PS C:\> ${My Variable} = "No a good way to do things"

${My Variable}

No a good way to do things

To get this to work, we have to encapsulate the variable name inside of curly brackets. This is not at all easy to read so I discourage it.

While working on a Group Policy issue, I needed a way to extract information from the Group Policy Settings Reference for Windows and Windows Server. This is an excel spread sheet.  I took the Administrative Templates sheet and saved it as an CSV file.  Once I did that, I could import in each record and use PowerShell to present GPO settings that fit my criteria.  Well, let’s import this data in and take a look at the property names.

PS C:\> Import-Csv -LiteralPath "C:\Users\JASON\Documents\PowerShell\InDevelopment\GPO\AdminTemplates2012.csv" |

    Get-Member -MemberType Properties |

    Select-Object -Property Name

 

Name

----              

Active Directory Schema or Domain Requirements                                                                       

File Name

Help Text

Logoff Required

Policy Path        

Policy Setting Name                                                                                                  

Reboot Required                      

Registry Information

Scope                                                  

Status

Supported On                                                             

Wow, not good. We have a lot of property names with spaces in them.  We have two choices here.  We can either just use the property names as is or we can modify them. 

Using them as is.

PS C:\> Import-Csv –LiteralPath "C:\AdminTemplates2012.csv" |

    Where {"$PSItem.Policy Path" -like "*Windows Components\Remote Desktop Service*"}

In the Where-Object line, we used double quotes surrounding the entire call to the object and the Policy Path” property.  Not as bad as using the curly brackets that we have to do for variables.  This will work.  For those of you who prefer to not uses spaces, we simple need to add some new properties to the object while getting ride of the old ones.

 

PS C:\> Import-Csv -LiteralPath "C:\AdminTemplates2012.csv" |

    ForEach-Object -Process {

        $Props = $PSItem | Get-Member -MemberType Properties | Select-Object -ExpandProperty Name

        $Obj = New-Object -TypeName PSObject

        ForEach ($P in $Props)

        {

            $Hash = @{NotePropertyName =  $P.Replace(" ","")

                      NotePropertyValue = $PSItem.$P}

            $Obj | Add-Member @Hash

        }

        Write-Output $Obj

        }

Yes, I know, a bit much.  Through this into a function and reuse it with other objects that suffer from spaces in the property names if you need to.  Really what we are achieving is creating a whole new object from the object created by Import-CSV.  This is one continuous command.  We are using ForEach-Object to cycle through one object at a time for processing.  The $Props variable stores the property names of each property in the object.  We then create a new object to pass out into the pipeline.  The NotePropertyName simply takes the name of the property being handled and removes all spaces from it.  The NotePropertyValue is the value of the original property.  Once all the properties have been renamed, the new object is sent to the pipeline so you can do what ever you need to do without the spaces.

Either way will work, you just need to choose which way you want to handle this “opportunity”.

Comments

Popular posts from this blog

Adding a Comment to a GPO with PowerShell

As I'm writing this article, I'm also writing a customization for a PowerShell course I'm teaching next week in Phoenix.  This customization deals with Group Policy and PowerShell.  For those of you who attend my classes may already know this, but I sit their and try to ask the questions to myself that others may ask as I present the material.  I finished up my customization a few hours ago and then I realized that I did not add in how to put a comment on a GPO.  This is a feature that many Group Policy Administrators may not be aware of. This past summer I attended a presentation at TechEd on Group Policy.  One organization in the crowd had over 5,000 Group Policies.  In an environment like that, the comment section can be priceless.  I always like to write in the comment section why I created the policy so I know its purpose next week after I've completed 50 other tasks and can't remember what I did 5 minutes ago. In the Group Policy module for PowerShell V3, th

Return duplicate values from a collection with PowerShell

If you have a collection of objects and you want to remove any duplicate items, it is fairly simple. # Create a collection with duplicate values $Set1 = 1 , 1 , 2 , 2 , 3 , 4 , 5 , 6 , 7 , 1 , 2   # Remove the duplicate values. $Set1 | Select-Object -Unique 1 2 3 4 5 6 7 What if you want only the duplicate values and nothing else? # Create a collection with duplicate values $Set1 = 1 , 1 , 2 , 2 , 3 , 4 , 5 , 6 , 7 , 1 , 2   #Create a second collection with duplicate values removed. $Set2 = $Set1 | Select-Object -Unique   # Return only the duplicate values. ( Compare-Object -ReferenceObject $Set2 -DifferenceObject $Set1 ) . InputObject | Select-Object – Unique 1 2 This works with objects as well as numbers.  The first command creates a collection with 2 duplicates of both 1 and 2.   The second command creates another collection with the duplicates filtered out.  The Compare-Object cmdlet will first find items that are diffe

How to list all the AD LDS instances on a server

AD LDS allows you to provide directory services to applications that are free of the confines of Active Directory.  To list all the AD LDS instances on a server, follow this procedure: Log into the server in question Open a command prompt. Type dsdbutil and press Enter Type List Instances and press Enter . You will receive a list of the instance name, both the LDAP and SSL port numbers, the location of the database, and its status.