It is probably a safe bet to say that IT Pros store a lot of information in simple text files. There's nothing with this. Notepad is ubiquitous and text files obviously easy to use. I bet you have text files of computer names, user names, service names, directories and probably a few that are unique to your company. Getting data out of these text files is very easy in PowerShell using Get-Content.
ManageEngine ADManager Plus - Download Free Trial
Exclusive offer on ADManager Plus for US and UK regions. Claim now!
get-content c:\work\computers.txt
The potential problem is that the text file may not be perfectly formatted. Your text file might have blank lines. Or your computername may have a trailing white space. These things can complicate using the text file in a PowerShell pipelined expression. One approach is to filter the content using Where-Object and simply look for the existing of something.
get-content c:\work\computers.txt | where {$_} | <something else>
This works fine in filtering out blank lines. But won't fail if you have a line where someone inserted a tab or hit the space bar a few times. So let's take this a bit further and use a regular expression to filter out anything that doesn't have a non-whitespace character.
get-content c:\work\computers.txt | where {$_ -match "\w+"} | <something else>
This should get rid of any lines that are nothing but tabs or spaces. Of course, there is still the issue of leading or trailing spaces. But we can handle that by using the string object's Trim() method.
This is starting to get complicated. So I wrote a filtering function to scrub up content presumably from text files.
#requires -version 2.0 Filter Scrub { <# .Synopsis Clean input strings .Description This command is designed to take string input and scrub the data, filtering out blank lines and removing leading and trailing spaces. The default behavior is to write the object to the pipeline, however you can use -PropertyName to add a property name value. If you use this parameter, the assumption is that contents of the text file are a single item like a computer name. .Example PS C:\> get-content c:\work\computers.txt | scrub | foreach { get-wmiobject win32_operatingsystem -comp $_} .Example PS C:\> get-content c:\work\computers.txt | scrub -PropertyName computername | test-connection #> [cmdletbinding()] Param( [Parameter(Position=0,ValueFromPipeline=$True)] [string[]]$InputObject, [string]$PropertyName ) #filter out blank lines $InputObject | where {$_ -match "\w+"} | ForEach-Object { #trim off trailing and leading spaces $clean = $_.Trim() if ($PropertyName) { #create a customobject property New-Object -TypeName PSObject -Property @{$PropertyName=$clean} } else { #write the clean object to the pipeline $clean } } #foreach } #close Scrub
We don't use the Filter keyword much anymore but it seemed appropriate because that is the only thing Scrub is doing. In fact, I intentionally did not use a traditional verb-noun name. Technically this an advanced function this is just a Process script block. I wrote it with the assumption that you would pipe strings from Get-Content.
Each processed string is filtered to get rid of blanks and spaces. Then each string is trimmed of leading and trailing spaces and finally written to the pipeline. Now I can run a command line this:
get-content c:\scripts\computers.txt | scrub
In my initial versions this solved all of my potential problems with text files. But then I realize I had an opportunity to add one more scrubbing feature. Many cmdlets have parameters that take pipeline input by property name. But strings from text files lack a property name. So I added a parameter to my Scrub filter to add a property name.
get-content c:\scripts\computers.txt | scrub -PropertyName Computername
Now I'm writing an object to the pipeline and can take advantage of pipeline binding.
get-content c:\scripts\computers.txt | scrub -PropertyName Computername | test-connection -Count 1
I don't know about you, but this will come in very handy. I hope you'll let me know what you think.
Jeff,
This will definitley come in handy. I’ve been trying to develop a filter for the same purpose but hadn’t figured out real pipeline output for it yet which left it partially crippled and requireing output to a new file and then an import to objectify the results. You’ve resolved exactly what I was stuck on in a very clear way and I apprecaite it. Now i’ve got several filters to update with the concept you demonstrated so clearly.
Thanks.
Thanks. Always glad to hear when a problem is solved.
I stink at regex, so I’ve done similar things with [String]::IsNullOrEmpty() or [String]::IsNullOrWhiteSpace().
Well I’m not very good at remembering or finding .NET methods.