Powershell Find All Files With String

admin

This article is a text version of a lesson from our PowerShell and Active Directory Essentials video course (use code ‘blog’ for free access).

  • List file names for all files not containing pattern: (Get-ChildItem -Recurse filespec. All it tells you is where you can find the files that contain the string. Improve this answer. With PowerShell, go to the path where your files are and then type this command and replace ENTER THE STRING.
  • The Get-Command cmdlet gets all commands that are installed on the computer, including cmdlets, aliases, functions, filters, scripts, and applications. Get-Command gets the commands from PowerShell modules and commands that were imported from other sessions. To get only commands that have been imported into the current session, use the ListImported parameter. Without parameters, Get-Command.

You can use it like Grep in UNIX and Findstr in Windows with Select-String in PowerShell. Select-String is based on lines of text. By default, Select-String finds the first match in each line and, for each match, it displays the file name, line number, and all text in the line containing the match. As you can see, it finds all of the 'Nebraska' entries under the Orders sheet but doesn't find anything on the other two sheets. You can use PowerShell to search for various pieces of data within an Excel workbook to include all of the worksheets, which can be useful to quickly determine how much of a particular piece of data is in the workbook.

The course has proven to be really popular as it walks you through creating a full Active Directory management utility from first principles.

Get the Free PowerShell and Active Directory Essentials Video Course

I'd recommend this for both new and advanced PowerShell users. Building an AD tool is a great learning experience.

What makes a PowerShell Object?

If there’s one thing you fundamental difference between PowerShell and other scripting languages that have come before, it’s PowerShell’s default use of Objects (structured data) instead of plain strings (undifferentiated blobs of data).

Consider something like a car. It has:

  • Colors
  • Doors
  • Lights
  • Wheels

These items that describe this particular object are called properties. Your car can also do things, it can turn left and right, it can move forward and back – these are the methods of the object.

Properties: the aspects and details of the object.
Methods: actions the object can perform.

What’s the PowerShell Pipeline?

PowerShell was inspired by many of the great ideas that make up “The Unix Philosophy” – most notable for us today are two points:

  1. Make each program do one thing well. To do a new job, build afresh rather than complicate old programs by adding new “features”.
  2. Expect the output of every program to become the input to another, as yet unknown, program. Don’t clutter output with extraneous information. Avoid stringently columnar or binary input formats. Don’t insist on interactive input.

In practice, what these somewhat abstract points of philosophy mean is that you should create lots of small, purposeful PowerShell scripts that each do a particular task. Every time you go to put an If/Else, another flag, another bit of branching logic, you should ask yourself: “Would this be better as a separate script?”

An example: don’t make a script that downloads a file and then parses the downloaded data. Make two scripts:

  1. One that downloads the data – download.ps
  2. A second that handles parsing the data into something usable – parse.ps

To get the data from the download.ps to parse.ps you would “pipe” the data in between the two scripts.

How to find the Properties and Methods of a PowerShell Object

There are way too many aspects of even the simplest object in PowerShell to remember. You need a way to interactively find out what each object you encounter can do as you’re writing your scripts can do.

The command you’ll need to do this is Get-Member cmdlet provided by Microsoft.

How To Use Get-Member

Get-Member helps reinforce an idea that I had a lot of difficulty grappling with in moving from bash to PowerShell scripting, that everything (literally everything) in PowerShell is an object. Let’s take a really simple example:

1. Use the Write-Output cmdlet to write some info into our PowerShell console.

Write-Output ‘Hello, World’

2. Assign that output to a variable called $string

$string = Write-Output `Hello, World`

3. Pipe the $string variable (That contains ‘Hello, World’) to the Get-Member cmdlet

$string Get-Member

You’ll get some output that looks like the screenshot below:

A list of properties and methods for this Object of type String. As the underlying data of the object changes so changes the responses of the methods and properties.

Some examples:

A string object of “Hello, World” has a length (property) of 13
A string object of “Hello, People of Earth!” has a length of 24

Calling Methods and Properties with Dot Notation

All of the Methods and Properties of an Object need to be called with a type of syntax called “Dot Notation” which is just a fancy way of saying:

OBJECT.PROPERTY

Some examples:

$string.Length
13

Methods are invoked in the say way, but parentheses are added.

$string.ToUpper()
HELLO, WORLD!

$string.ToLower()
hello, world!

Both of these methods don’t take any “arguments” – additional commands passed in as parameters within the parentheses.

$string.Replace(‘hello’,’goodbye’)
Goodbye, world!

The Replace method does, the first argument is what you’re looking for in the string ‘hello’ and the second is what you’d like to replace it with.

How to Make our Own PowerShell Objects

Find

Our $string variable that we created was of Type System.String – but what if we wanted to create our own type of object instead of relying upon the built-in types?

1. Create HashTable

A hash table is a Key + Value datastore where each ‘key’ corresponds to a value. If you’ve ever been given an employee number at a job or had to fill out a timesheet with codes given to each company you’ll be familiar with the concept.

$hashtable = @{ Color = ‘Red’; Transmission = ‘Automatic’; Convertible = $false}

If you pipe this to Get-Member you’ll now get a different listing of methods and properties because it’s a different Type (it’s System.Collections.Hashtable instead of System.String).

2. Creating a PowerShell Custom Object

To transform this from a hashtable to a full-blown PowerShell Object, we’ll use what’s called a “type accelerator” ->pscustomobject – [pscustomobject]$hashtable

When we run this and compare the results to what we have previously with Get-Member you’ll notice a wild difference. Gone are the generic methods and properties of a hashtable and instead are the properties that you had specified (Color, Transmission and whether or not it was a Convertible).

Getting Into the Pipeline

Some people get really hung up on what’s the difference between a script and an application. In general, scripts are small and do one very concise action. Applications are large (comparatively) and bundle together tons of features.

Consider the approach to exposing functionality in Microsoft Word versus how similar features would be presented as a series of scripts.

In Word, the word count is continually displayed in the status bar at the bottom of the editing window.

You can click it and get more detailed statistics (one of the many thousands of features in Microsoft Word).

In PowerShell scripting you’d use two separate cmdlets to achieve this functionality:

Get-Content will import a text file as an object (everything in PowerShell is an object) and Measure-Object will then collect statistics about that object for us.

Putting it together you’d have:

Get-Content c:documentsmyfile.txt Measure-Object -word

The ` ` character in between the two commands is the “pipe” which indicates that instead of displaying the output of the Get-Content command in the PowerShell command window, it should instead pass that data to the next script (the Measure-Object cmdlet).

Now, you might be looking at this example and thinking to yourself: “That’s a very convoluted way to finding out how many words are in a file” and you wouldn’t be wrong, But the important thing to consider is that the scripting doesn’t “care” what comes before the pipe.

Instead of importing a single file, maybe we’re writing a novel with 60 different chapters (one chapter per file), we could concatenate all of those files together and pipe the result to Measure-Object and get a word count for the whole book in one go.

How to Use the Pipeline

As a more practical example of using piping for sysadmin tasks, let us try to find and restart a service with PowerShell.

For this, we’re going to be using two cmdlets:

To start, we can walk through the steps as if we were doing everything manually.

First, let’s look for the Windows Audio Service

Get-Service -Name audiosrv

If you’re in PowerShell (look for the PS prompt) – you should get something that looks like:

And having found the service is present, we could then restart it.

Restart-Service -Name audiosrv

If we’re using pipelines, we could instead pipe the entire object into the Restart-Service cmdlet.

Get-Service -Name audiosrv Restart-Service

The above is functionally the same but happens as a single command

To extend this further, we can use the -PassThru command to keep passing the input object through each script.

Get-Service -Name audiosrv Restart-Service -PassThru Stop-Service

Through this, we’re able to apply a number of command to the same initial object.

Now for a more real-world example.

Pinging a Collection of Computers with PowerShell

To start, we have a number of computer hostnames (one per line) in a text file.

Your first instinct might be to try and directly pass the file to the Test-Connection cmdlet, like:

Get-Content -Path C:Example.txt Test-Connection

However, we still need to be cognizant of what type of object is being passed. The above is passing in the file as if it was a chapter in a book, it’s not sure what to do with it. We need to first format the file data into the expected format.

Photoscape x for mac. To figure that out, we turn to the Get-Help cmdlet

Get-Help -Name Test-Connection -Full

“Full” indicates that the parameter listings should include not just the names and usage, but also whether or not they accept pipeline input, and if they do, what format.

In the above screenshot, you can see the “Accept pipeline input?” is True and indicates that it accepts input via a Property Name (instead of an object).

Powershell Find All Files With String Banjo

The following will extract each line of the input file and transform it via the pscustomobject command into a property name (as required by the Test-Connection cmdlet.

Get-Content -Path C:Example.txt ForEach-Object { [pscustomobject]@{ComputerName = $PSItem} } Test-Connection

Next Steps with PowerShell

Want to learn more? Use unlock code ‘blog’ for free access to the full PowerShell and Active Directory Essentials video course.

Introduction to Windows PowerShell Select-String

Select-String not only opens a file, but also checks for a word, a phrase, or in fact any pattern match. If you have used -pattern to make changes, PowerShell also tidies up and closes the file automatically.

Topics for PowerShell Select-String

Introduction to: Select-String

The first objective is to set the -pattern parameter, which defines the string we are seeking. Next comes the -path parameter, and as its name indicates, -path directs Select-String to the file’s location.

As you are reading this introduction, I expect you are thinking of possible applications for this Select-String construction. Perhaps you wish to discover which documents contain a particular word? Alternatively, you may be seeking a more complex search-And-replace operation. My point is that while Select-String may be a bit-part in a bigger drama, you still need to master its syntax and switches.

Example 1 Select-String -path -pattern

The key to understanding Select-String is focussing on the two main switches -path and -pattern. They say to me, ‘Where is the input?’ and, ‘What pattern do you want to match?’

To ensure that my examples work on your machine, you and I need to agree on the file location and the pattern to search. To follow my examples successfully you need to embrace one of two tactics, either mimic my folder structure and patterns, or amend my script to fit in with your environment.

My folder happens to be called : D: powershellstuff. These days I operate with the ISE version of PowerShell v 3.0. Previously I navigated in PowerShell to the folder where I stored the files with the cmdlet examples that I am testing. Then I just issue the .filename command (.Dot slash followed by the name of cmdlet which stores the PowerShell instructions).

Here are three simple scripts which all produce the same result, but each employs a slightly different method. By studying all three you will gain both perspective and ideas for the best method to use in your scripts.

Assumptions:
You have a file called gopher.txt.
In gopher.txt is the word Guido.

Example 1a Select-String

Instructions

  1. Let us create the appropriate file in the appropriate folder, for example gopher.txt in D:powershellstuff.
  2. Put the word that you wish to search for in gopher.txt. My word, is ‘Guido’, and you can see that in the script it comes directly after the -pattern parameter.
  3. Type this one line at the PowerShell command line:

Select-String -pattern 'Guido' -path 'D:powershellstuffgopher.txt'

Note 1: Look closely at the dashes ‘-‘ PowerShell’s Verb-Noun (Select-String) pair are joined by a dash with no spaces. The parameters -path and -pattern are introduced by a space dash then the parameter itself.

Example 1b Select-String Using the Variable $Location

This example is more complicated in that we are going to create a cmdlet, copy and paste the code below, then execute the cmdlet from inside PowerShell.

  1. Copy the cmdlet, then paste it into notepad, remember to save with a .ps1 extension,
    for example: selectstr.ps1.
  2. Then I navigate in PowerShell to the folder where I saved the file, for example D: powershellstuff
  3. Issue the command .selectstr
  4. If all else fails copy and paste the two lines into the PowerShell command line, then press ‘Enter’.

# PowerShell cmdlet to find the pattern Guido
$Location = 'D:powershellstuffgopher.txt'
Select-String -pattern 'Guido' -path $Location

Expected outcome:
D:powershellstuffgopher.txt:3:Guido is king

:3: Means line number 3
:Guido is king Refers to the line where the Pattern 'Guido' occurs.

Guy Recommends: A Free Trial of the Network Performance Monitor (NPM) v11.5

SolarWinds’ Network Performance Monitor will help you discover what’s happening on your network. This utility will also guide you through troubleshooting; the dashboard will indicate whether the root cause is a broken link, faulty equipment or resource overload.

What I like best is the way NPM suggests solutions to network problems. Its also has the ability to monitor the health of individual VMware virtual machines. If you are interested in troubleshooting, and creating network maps, then I recommend that you try NPM now.

Example 1c Select-String (Wildcards *.*)

It is often useful to search a batch of files. The simplest method is to use the famous * or *.* wildcard.

Instructions are the same as for example 1a

# PowerShell cmdlet to find the pattern Guido. Note wildcard *
Select-String -pattern 'Guido' -path 'D:powershellstuff*.*'

Example 1d Select-String (Guy’s indulgence)

Powershell Search For Text In Files

My main idea in Example 1c is to introduce an If… Else clause to cater for instances where the -pattern cannot be found. To prepare for the ‘If’ logic I have introduced another variable called $SearchStr. The second time you run this script you may wish to find and amend the 'zzz' to a value that will ensure success. If you accept my challenge then you can compare the outcome of the ‘If’ clause with the outcome of the ‘Else’ clause.

Instructions are the same as for example 1a

# PowerShell cmdlet to find the pattern zzz.
$Location = 'D:powershellstuffgopher.txt'
$SearchStr = 'zzz'
$Sel = Select-String -pattern $SearchStr -path $Location
If ($Sel -eq $null)
{
write-host '$Location does not contain $SearchStr'
}
Else
{
write-host 'Found `n$Sel'
}

Write-host 'end'

Note 2: Let us study the ‘If’ test: If ($Sel -eq $null) What this says if the value returned by Select-String is nothing ($Null). Incidentally, there are two lls in $null. Also, the correct syntax is -eq and not plain old =.

Note 3: The purpose of `n is to force a carriage return.

Note 4: Once the script runs successfully, amend $SearchStr ='zzz' to a string that exists in your document.

Guy Recommends: SolarWinds Engineer’s Toolset v10

This Engineer’s Toolset v10 provides a comprehensive console of 50 utilities for troubleshooting computer problems. Guy says it helps me monitor what’s occurring on the network, and each tool teaches me more about how the underlying system operates.

There are so many good gadgets; it’s like having free rein of a sweetshop. Thankfully the utilities are displayed logically: monitoring, network discovery, diagnostic, and Cisco tools. Try the SolarWinds Engineer’s Toolset now!

Footnote – More parameters:

In addition to -pattern and -path, Select-String has more parameters; -Include and -exclude which are useful for fine tuning the files to be searched. There is also the -caseSensitive switch to control uppercase and lowercase in the -pattern. Select-String, like most PowerShell commands, is not case sensitive by default, hence the -caseSensitive parameter.

Traps with Select-String

The biggest trap with all PowerShell’s file handling commands is ‘overthink’ By that I mean wasting time looking for open-file or save-file commands, which simply don’t exist. What happens is that PowerShell opens, closes and saves files automatically.

A Real-life Example of Select-String

My practical problem was that I wanted to search for instances a particular string in a directory with hundreds of file. If a file had duplicate entries, then I needed to know.

The PowerShell problem is how to create a stream of the files, then compare each file with my string value. In the output I needed to know the filename.

To solve the problem, I employed four main commands, which you can see in the following script:

  1. Get-ChildItem – recurse
  2. foreach (loop) {what to do block}
  3. if (test) {output block}
  4. Select-String -pattern to match my string value.

# A real-life example of PowerShell’s Select-String
$i=0
$File = Get-ChildItem 'H:sports' -Include *.htm -recurse
$StringVid = 'themesguy/google'
foreach ($Entry in $File) {
$List = Select-String -pattern $StringVid $Entry
if ($List.LongLength -gt 1) {
'{0,-8} {1,-4} {2,18}' -f
'Files ', $List.LongLength, $Entry.FullName;
$i++
}
}

Learning Point

Note 5: If you want to get the above script to work, focus on the $File and $StringVid variables. Specifically change their values to match your file location and search pattern.

Note 6: To find out more about the -f formatting switch consult SN4 in the Syntax section.

Guy Recommends: SolarWinds Free Network Bandwidth Monitor

This freeware monitor is great for checking whether your network’s load-balancing is performing as expected, for example, are two interfaces are getting about equal traffic?

It’s easy to install and straightforward to configure. You will soon be running tests to see how much network bandwidth your applications consume.

The GUI has a lovely balance between immediate network traffic data in the middle, combined with buttons to seek related data and configuration settings. Give this monitor a try, it’s free!

If you need more comprehensive network analysis software:
Download a free trial of NPM (Network Performance Monitor)

Example of Select-String Kindly Sent by trebboR

# A real-life example of PowerShell’s Select-String
# Makes a test.txt file with testcontent
'0123456789abcdefghijklmnopqrstuvwxyz`
ABCDEFGHIJKLMNOPQRSTUVWXYZZYXWVUTSRQPONMLKJIHGFEDCBA`
zyxwvutsrqponmlkjihgfedcba9876543210' >> 'C:test3.txt'
# read file into $a
$a = Get-Content 'C:test3.txt'
#$a
# Check what you want
$a.Contains('zz') #False
$a.Contains('ZZ') #True
$a.IndexOf('ZZ') # 61
#-=[trebboR.EU]=-

Further Research on PowerShell’s Select-String

I found these the most useful Select-String parameters -Include, -Context and -NotMatch. I have found -Exclude disappointing, particularly in PowerShell v 1.0.

Select-String -Context

# PowerShell Select-String -Context
$FilePath = 'D:powershellstuff*.*
Select-String -pattern 'Guido' -path $FilePath -context 3

Note 7: This returns 3 lines either side of the pattern Guido, just so that you can see which of multiple results you is most interesting. One use of this technique is troubleshooting eventlogs. I also recommend splatting to format your parameters.

Sister Cmdlet – Out-String

The only other cmdlet with the noun ‘string’ is: Out-String.

Note 8: In PowerShell Select-String has an alias called: sls.

Summary of PowerShell’s Select-String Cmdlet

Select-String is a useful instruction for opening files, and then searching their contents for the phrase specified by the -pattern parameter. My advice is to get into the rhythm of the command: for example: Verb-Noun then -parameter. For example: Select-String -path -pattern. As expected, you can use wildcards in the path.

Once you have mastered the basic construction look real life tasks where you can employ this technique to find words or phrases that are hiding somewhere within your files.

If you like this page then please share it with your friends

See more PowerShell examples for syntax constructions

• PowerShell Tutorials • Syntax • Pipeline • Quotes • Remove-Item • ItemProperty

• Select-String • -replace string • Group-Object • Sort-Object • PowerShell Splatting

• Windows PowerShell cmdlets • Windows PowerShell • New-Item • PowerShell New Object

Please email me if you have a better example script. Also please report any factual mistakes, grammatical errors or broken links, I will be happy to correct the fault.