PowerShell for Windows Admins


January 16, 2013  4:21 PM

Account SIDs

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

A question on the forum asked about finding the accounts and SIDs on the local machine.

function get-SID {            
param (            
 [string]$computername = $env:COMPUTERNAME            
)            
            
Get-WmiObject -Class Win32_AccountSID -ComputerName $computername |            
foreach {            
 $da =  (($_.Element).Split(".")[1]).Split(",")            
 $sid = ($_.Setting -split "=")[1] -replace '"',''            
            
 $props = [ordered]@{            
 Domain = ($da[0] -split "=")[1] -replace '"',''            
 Account = ($da[1] -split "=")[1] -replace '"',''            
 SID = $sid            
 }            
             
 New-Object -TypeName PSObject -Property $props            
}            
            
}

Pass a computer name into the function – default is local machine.

Use the AccountSID class which links Win32_SystemAccount and Win32_SID.  For each returned instance clean up the data and create an object with three properties – domain, account and SID.

You will see more than you thought – some very useful information buried in there

January 16, 2013  2:29 PM

UK PowerShell group – 29 January 2013

Richard Siddaway Richard Siddaway Profile: Richard Siddaway


When: Tuesday, Jan 29, 2013 7:30 PM (GMT)


Where: virtual

*~*~*~*~*~*~*~*~*~*

Active Directory is one of the commonest automation targets for administrators. This session will covert the basics of automating your AD admin – scripts and the Microsoft cmdlets. The new features in PowerShell for Windows 2012 AD will also be covered

Notes


Richard Siddaway has invited you to attend an online meeting using Live Meeting.
Join the meeting.
Audio Information
Computer Audio
To use computer audio, you need speakers and microphone, or a headset.
First Time Users:
To save time before the meeting, check your system to make sure it is ready to use Microsoft Office Live Meeting.
Troubleshooting
Unable to join the meeting? Follow these steps:

  1. Copy this address and paste it into your web browser:
    https://www.livemeeting.com/cc/usergroups/join
  2. Copy and paste the required information:
    Meeting ID: RCRWH3
    Entry Code: 5p7$}S_!h
    Location: https://www.livemeeting.com/cc/usergroups

If you still cannot enter the meeting, contact support

Notice
Microsoft Office Live Meeting can be used to record meetings. By participating in this meeting, you agree that your communications may be monitored or recorded at any time during the meeting.


January 16, 2013  12:18 PM

PowerShell wins award

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

PowerShell has won one on InfoWorld’s Technology of the Year awards for 2013

See http://www.infoworld.com/slideshow/80986/infoworlds-2013-technology-of-the-year-award-winners-210419#slide24

for details


January 16, 2013  11:02 AM

Workflow article 4

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

The next in the series of articles on PowerShell workflows that are appearing on the Scripting Guy blog has been published.

The articles in the series that have been published are:

http://blogs.technet.com/b/heyscriptingguy/archive/2012/12/26/powershell-workflows-the-basics.aspx
http://blogs.technet.com/b/heyscriptingguy/archive/2013/01/02/powershell-workflows-restrictions.aspx
http://blogs.technet.com/b/heyscriptingguy/archive/2013/01/09/powershell-workflows-nesting.aspx
http://blogs.technet.com/b/heyscriptingguy/archive/2013/01/16/powershell-workflows-job-engine.aspx

Look for the next article in one weeks time.

Until then Enjoy!


January 15, 2013  3:38 PM

Updating Help on PowerShell v3

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

One of the new features in PowerShell v3 is the capability to update the help files. In fact you have to do this because PowerShell v3 doesn’t ship with any help files. Since Windows 8 RTM’d there have been a succession of new help files released.

I discovered one of my netbooks didn’t have the latest version of the help files installed. So I needed to update them. This got me thinking that it would be better if the machine did this for me.

I could think of two easy ways to do this – a scheduled job or a scheduled task. I chose the scheduled task because the ScheduledTasks module is available on the version of PowerShell v3 for Windows 7 and other legacy versions of Windows. The PSScheduledJob module is only available on Windows 8/2012 as it’s based on WMI classes not present on older versions of Windows.

$actionscript = '-NonInteractive -WindowStyle Normal -NoLogo -NoProfile -NoExit -Command "& {Update-Help -UICulture en-US -Force}"'            
$pstart =  "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"            
#$days = "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"             
$days = 'Wednesday'            
            
Get-ScheduledTask -TaskName UpdatePSHelp | Unregister-ScheduledTask -Confirm:$false            
            
$act = New-ScheduledTaskAction -Execute $pstart -Argument $actionscript            
$trig = New-ScheduledTaskTrigger -Weekly -WeeksInterval 4 -At 19:00 -DaysOfWeek $days            
Register-ScheduledTask -TaskName UpdatePSHelp -Action $act -Trigger $trig -RunLevel Highest

Start by creating the command strings to start PowerShell and the arguments you pass to it.  I left it as a visible PowerShell window that stays opn so I can see the results. The PowerShell command

Update-Help -UICulture en-US –Force

performs the actual update.  You will need to change the culture to match yours if you aren’t using English.  You can find it by using

Get-UICulture

I’m only going to run this on Wednesdays .

Any old copies of the task are cleaned out and new task actions (to execute PowerShell) and trigger to define when it runs are created. The last line registers the task.

You can view the task

Get-ScheduledTask -TaskName UpdatePSHelp

or start the task manually

Start-ScheduledTask -TaskName UpdatePSHelp


January 11, 2013  1:40 PM

Select-string – keeping in context

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

 

Today’s question involves using the Context parameter:

It’s probably just me, but I’ve never gotten the switch ‘-context 5
or -context 2, 7′ to work predictably – where 5 lines before and after or 2
before and 7 after will come out – have you?

Let’s start by looking at the default behaviour of select-string using the search pattern you’ve seen previously:

PS> Select-String -Path c:\test\*.txt -Pattern "\A\w{5}ABCD"

C:\test\fixedcol.txt:1:12345ABCD123451234512345

C:\test\fixedcol.txt:3:12345ABCD123451234512345

C:\test\fixedcol.txt:4:12345abcd123451234512345

C:\test\fixedcol.txt:6:12345ABCD123451234512345

C:\test\fixedcol2.txt:1:12345ABCD123451234512345

As you can see the line which matches your pattern is returned.  Often this is all that is required but there are occasions when you need to be able to put the line into context that is you need to understand how the line containing you pattern relates to the data around it.  The is what the context parameter can provide. 

If you look at the Select-String help file you will find this information on context.

-Context <Int32[]>       

Captures the specified number of lines before and after the line with the match. This allows you to view the match in context.               

Required?                    false       

Position?                    named       

Default value                       

Accept pipeline input?       false       

Accept wildcard characters?  false

The first thing to note is that the parameter takes an array of integers. The first (or only member of the array) tells PowerShell how many lines to show from before and after the matching line while the second member of the array controls the number of lines that are displayed after the matching line. Put simply if you supply one values it controls the number of lines from before and after you match that are displayed but if you specify two values then you explicitly control the lines from before the match with the first value and the lines from after the match with the second. Some examples should make this clear.

I’m going to use a file where we know the contents – it makes the explanations easier. If you run this:

Get-Process | sort CPU -Descending | Out-File -FilePath c:\test\proc.txt –Force

You get a text file with the processes listed by CPU usage. You can examine the file for a particular process – this case let’s look at Word:

PS> Select-String -Path c:\test\*.txt -Pattern "Winword" -SimpleMatch

 

C:\test\proc.txt:8:    360      25    20368      61728   331    41.89   4976 WINWORD

You know that the file is ordered by CPU usage so what are the processes using similar amounts of CPU to Word?

PS> Select-String -Path c:\test\*.txt -Pattern "Winword" -SimpleMatch -Context 2

 

  C:\test\proc.txt:6:    653      34    66640      94416   286    48.77   3724 powershell

  C:\test\proc.txt:7:   1124      29    13912      19336   210    47.71   5868 LiveComm

> C:\test\proc.txt:8:    360      25    20368      61728   331    41.89   4976 WINWORD

  C:\test\proc.txt:9:    212       9     2788      10956    78    28.67   4112 SynTPEnh

  C:\test\proc.txt:10:   565      35    49172      82572   347    12.50   5660 WWAHost

 

The matching line is marked with a > symbol. I’ve made it bold in the above listing for emphasis.

If you specify a number such that the file doesn’t have enough lines to display then only those lines that are available will be displayed for instance

Select-String -Path c:\test\*.txt -Pattern "Winword" -SimpleMatch -Context 12

This can only display the seven lines prior to the match so that’s all it does.

What about the situation where you only want the three processes that are using more CPU than Word?

PS> Select-String -Path c:\test\*.txt -Pattern "Winword" -SimpleMatch -Context 3,0

 

  C:\test\proc.txt:5:   1555      74    30660      87176   465    80.70   5308 explorer

  C:\test\proc.txt:6:    653      34    66640      94416   286    48.77   3724 powershell

  C:\test\proc.txt:7:   1124      29    13912      19336   210    47.71   5868 LiveComm

> C:\test\proc.txt:8:    360      25    20368      61728   331    41.89   4976 WINWORD

This works as well

PS> Select-String -Path c:\test\*.txt -Pattern "Winword" -SimpleMatch -Context 3,$null

 

  C:\test\proc.txt:5:   1555      74    30660      87176   465    80.70   5308 explorer

  C:\test\proc.txt:6:    653      34    66640      94416   286    48.77   3724 powershell

  C:\test\proc.txt:7:   1124      29    13912      19336   210    47.71   5868 LiveComm

> C:\test\proc.txt:8:    360      25    20368      61728   331    41.89   4976 WINWORD

The one thing you can’t do is this:

PS> Select-String -Path c:\test\*.txt -Pattern "Winword" -SimpleMatch -Context 3,

>> 

PowerShell expects something after the comma and will prompt you to supply it.

The converse holds true if you want the lines that occur after the match. You can use a 0 as the first element:

PS> Select-String -Path c:\test\*.txt -Pattern "Winword" -SimpleMatch -Context 0,3

 

> C:\test\proc.txt:8:    360      25    20368      61728   331    41.89   4976 WINWORD

  C:\test\proc.txt:9:    212       9     2788      10956    78    28.67   4112 SynTPEnh

  C:\test\proc.txt:10:    565      35    49172      82572   347    12.50   5660 WWAHost

  C:\test\proc.txt:11:    276      19     6608      12628    88     9.33   5252 taskhostex

Or $null

PS> Select-String -Path c:\test\*.txt -Pattern "Winword" -SimpleMatch -Context $null,3

 

> C:\test\proc.txt:8:    360      25    20368      61728   331    41.89   4976 WINWORD

  C:\test\proc.txt:9:    212       9     2788      10956    78    28.67   4112 SynTPEnh

  C:\test\proc.txt:10:    565      35    49172      82572   347    12.50   5660 WWAHost

  C:\test\proc.txt:11:    276      19     6608      12628    88     9.33   5252 taskhostex

 

You can’t leave the first element blank

PS> Select-String -Path c:\test\*.txt -Pattern "Winword" -SimpleMatch -Context ,3

At line:1 char:76

+ Select-String -Path c:\test\*.txt -Pattern "Winword" -SimpleMatch -Context ,3

+                                                                            ~

Missing argument in parameter list.

    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException

    + FullyQualifiedErrorId : MissingArgument

This leads to the situation where you need to display a different number of lines before and after the match:

PS> Select-String -Path c:\test\*.txt -Pattern "Winword" -SimpleMatch -Context 3,2

 

  C:\test\proc.txt:5:   1555      74    30660      87176   465    80.70   5308 explorer

  C:\test\proc.txt:6:    653      34    66640      94416   286    48.77   3724 powershell

  C:\test\proc.txt:7:   1124      29    13912      19336   210    47.71   5868 LiveComm

> C:\test\proc.txt:8:    360      25    20368      61728   331    41.89   4976 WINWORD

  C:\test\proc.txt:9:    212       9     2788      10956    78    28.67   4112 SynTPEnh

  C:\test\proc.txt:10:    565      35    49172      82572   347    12.50   5660 WWAHost

What happens if you have multiple matches and their contexts overlap?

PS> Select-String -Path c:\test\*.txt -Pattern "PowerShell" -SimpleMatch

 

C:\test\proc.txt:9:    669      34    67544      62228   286    54.99   3724 powershell

C:\test\proc.txt:12:    473      23    69112      86616   366    11.73   1688 powershell_ise

C:\test\proc.txt:19:    346      13    39576      44540   207     3.15    280 PowerShell

This file shows matches on lines 9, 12 and 19 so let’s try this

PS> Select-String -Path c:\test\*.txt -Pattern "PowerShell" -SimpleMatch -Context 4,5

 

  C:\test\proc.txt:5:   1840      91    35836      75652   545   142.49   5308 explorer

  C:\test\proc.txt:6:    618      23    68524      28788   194   108.84   5072 SkyDrive

  C:\test\proc.txt:7:   1377      29    15668      23440   210    95.07   5868 LiveComm

  C:\test\proc.txt:8:    211       9     2792       4516    78    59.98   4112 SynTPEnh

> C:\test\proc.txt:9:    669      34    67544      62228   286    54.99   3724 powershell

  C:\test\proc.txt:10:    560      35    53480      88760   370    22.95   2656 WWAHost

  C:\test\proc.txt:11:    240       8     1952       2340    71    12.32   5580 TabTip

> C:\test\proc.txt:12:    473      23    69112      86616   366    11.73   1688 powershell_ise

  C:\test\proc.txt:13:    254       9     4684       9940    86    11.31   6136 RuntimeBroker

  C:\test\proc.txt:14:    285      14     4116       4724    84    10.19   5252 taskhostex

  C:\test\proc.txt:15:     82       5     2008       6148    55     7.52   2416 conhost

  C:\test\proc.txt:16:    305      14    17608       5088   184     5.19    404 IAStorIcon

  C:\test\proc.txt:17:    337       8     2180        536    76     4.79    376 InputPersonalization

  C:\test\proc.txt:18:    409      12     4416       5464    79     4.26   5276 taskhost

> C:\test\proc.txt:19:    346      13    39576      44540   207     3.15    280 powershell

  C:\test\proc.txt:20:    125       5     2820        744    70     2.61    908 splwow64

  C:\test\proc.txt:21:    347      13    12180        804   183     2.40   4788 PopUp_DM

  C:\test\proc.txt:22:    335      10     2576       1756    83     2.20   4636 AdobeARM

  C:\test\proc.txt:23:    249      21     6628        540   129     1.44   5220 SRSPremiumPanel

  C:\test\proc.txt:24:    387      11     3436      12280    83     0.94   3828 WSHost

I’ve highlighted the lines that actually match.

Starting with the first match you get 4 lines before it as requested. There should be 5 lines after the match BUT the next match is only 3 lines on and you asked for 5 lines after that. The lines before the last match overlap the lines after the second match. The lines after the last match are shown as requested.

At first glance it looks like the command hasn’t worked but what seems to be happening is that only unique lines are displayed.

I looked at the individual matches

$finds = Select-String -Path c:\test\*.txt -Pattern "PowerShell" -SimpleMatch -Context 4,5

for ($i=0; $i -le $finds.count; $i++){$finds[$i]; "###"*8}

and received this output (I’ve split the display so you can see what is produced.

First match:

  C:\test\proc.txt:5:   1840      91    35836      75652   545   142.49   5308 explorer

  C:\test\proc.txt:6:    618      23    68524      28788   194   108.84   5072 SkyDrive

  C:\test\proc.txt:7:   1377      29    15668      23440   210    95.07   5868 LiveComm

  C:\test\proc.txt:8:    211       9     2792       4516    78    59.98   4112 SynTPEnh

> C:\test\proc.txt:9:    669      34    67544      62228   286    54.99   3724 powershell

  C:\test\proc.txt:10:    560      35    53480      88760   370    22.95   2656 WWAHost

  C:\test\proc.txt:11:    240       8     1952       2340    71    12.32   5580 TabTip

########################

Correct number before but restricted output after

Second match:

> C:\test\proc.txt:12:    473      23    69112      86616   366    11.73   1688 powershell_ise

  C:\test\proc.txt:13:    254       9     4684       9940    86    11.31   6136 RuntimeBroker

  C:\test\proc.txt:14:    285      14     4116       4724    84    10.19   5252 taskhostex

  C:\test\proc.txt:15:     82       5     2008       6148    55     7.52   2416 conhost

  C:\test\proc.txt:16:    305      14    17608       5088   184     5.19    404 IAStorIcon

  C:\test\proc.txt:17:    337       8     2180        536    76     4.79    376 InputPersonalization

########################

Nothing before and correct output after the match

Last match:

 C:\test\proc.txt:18:    409      12     4416       5464    79     4.26   5276 taskhost

> C:\test\proc.txt:19:    346      13    39576      44540   207     3.15    280 powershell

  C:\test\proc.txt:20:    125       5     2820        744    70     2.61    908 splwow64

  C:\test\proc.txt:21:    347      13    12180        804   183     2.40   4788 PopUp_DM

  C:\test\proc.txt:22:    335      10     2576       1756    83     2.20   4636 AdobeARM

  C:\test\proc.txt:23:    249      21     6628        540   129     1.44   5220 SRSPremiumPanel

  C:\test\proc.txt:24:    387      11     3436      12280    83     0.94   3828 WSHost

########################

One line before the match and correct number after the match.

This confirms that if a line has appeared in a previous match you won’t see it again. Is there a way to see the full context for each match? Unfortunately, Select-String doesn’t appear to provide that capability directly. A little bit of working with the output should enable this.

Select-String -Path c:\test\*.txt -Pattern "PowerShell" -SimpleMatch -Context 4,5 |

foreach {

#matching line

$padlength = (" {0}:{1:00}: " -f $_.Path, $_.LineNumber).Length

$pad = " "*$padlength

 

$_.Context.PreContext | foreach {$_.Trim().Insert(0,$pad)}

""

" {0}:{1:00}: {2}" -f $_.Path, $_.LineNumber, ($_.Line).Trim()

""

$_.Context.PostContext | foreach {$_.Trim().Insert(0,$pad)}

""

""

}

 

Run the select-string as before. For each of the matches find the length of the formatted path and line number and create a blank string of that length.

If you examine the MatchInfo type that Select-String produces you will see a Property called Context. If you examine that you will see it contains the collection of data for the pre and post context. (There are also display versions of the context). 

For each line in the pre-context insert the pad characters at the beginning. Display the formatted match line and then display the post-context data.  I’ve inserted some blank lines to help format the display

You will get output like this:

                       1840      91    35836      75652   545   142.49   5308 explorer

                      618      23    68524      28788   194   108.84   5072 SkyDrive

                      1377      29    15668      23440   210    95.07   5868 LiveComm

                      211       9     2792       4516    78    59.98   4112 SynTPEnh

 

 C:\test\proc.txt:09: 669      34    67544      62228   286    54.99   3724 powershell

 

                      560      35    53480      88760   370    22.95   2656 WWAHost

                      240       8     1952       2340    71    12.32   5580 TabTip

                      473      23    69112      86616   366    11.73   1688 powershell_ise

                      254       9     4684       9940    86    11.31   6136 RuntimeBroker

                      285      14     4116       4724    84    10.19   5252 taskhostex

 

 

                      211       9     2792       4516    78    59.98   4112 SynTPEnh

                      669      34    67544      62228   286    54.99   3724 powershell

                      560      35    53480      88760   370    22.95   2656 WWAHost

                      240       8     1952       2340    71    12.32   5580 TabTip

 

 C:\test\proc.txt:12: 473      23    69112      86616   366    11.73   1688 powershell_ise

 

                      254       9     4684       9940    86    11.31   6136 RuntimeBroker

                      285      14     4116       4724    84    10.19   5252 taskhostex

                      82       5     2008       6148    55     7.52   2416 conhost

                      305      14    17608       5088   184     5.19    404 IAStorIcon

                      337       8     2180        536    76     4.79    376 InputPersonalization

 

 

                      82       5     2008       6148    55     7.52   2416 conhost

                      305      14    17608       5088   184     5.19    404 IAStorIcon

                      337       8     2180        536    76     4.79    376 InputPersonalization

                      409      12     4416       5464    79     4.26   5276 taskhost

 

 C:\test\proc.txt:19: 346      13    39576      44540   207     3.15    280 powershell

 

                      125       5     2820        744    70     2.61    908 splwow64

                      347      13    12180        804   183     2.40   4788 PopUp_DM

                      335      10     2576       1756    83     2.20   4636 AdobeARM

                      249      21     6628        540   129     1.44   5220 SRSPremiumPanel

                      387      11     3436      12280    83     0.94   3828 WSHost

Not the greatest of displays but you do get to see the data. It should be possible to do this through PowerShell’s formatting system but that’s a post for another day.

Bottom line – the context parameter only displays unique lines so you won’t necessarily get what you expect if there are multiple matches in a file.


January 9, 2013  11:57 AM

Select-String – finding the first and last matches

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Today’s question concerns finding the first and last matches in a file

Sometimes, I need to make two passes at seeking content in this file, once for the first occurrence; and a second grep for obtaining the last occurrence of a phrase. After the second pass, I figure placing the values into an array is the best way, then need to combine first and last values onto one output line {somewhere else}.

Let’s consider the file we used in the first article in the series – http://msmvps.com/blogs/richardsiddaway/archive/2013/01/07/select-string-scenarios-fixed-columns.aspx

The file looks like this

12345ABCD123451234512345
1234512345ABCD1234512345
12345ABCD123451234512345
12345abcd123451234512345
123451234512345ABCD12345
12345ABCD123451234512345
123451234512345ABCD12345
12345123451234512345ABCD
1234512345ABCD1234512345

If you this select-string

Select-String -Path c:\test\*.txt -Pattern "\A\w{5}ABCD

you will get multiple matches

C:\test\fixedcol.txt:1:12345ABCD123451234512345
C:\test\fixedcol.txt:3:12345ABCD123451234512345
C:\test\fixedcol.txt:4:12345abcd123451234512345
C:\test\fixedcol.txt:6:12345ABCD123451234512345

So, how can we find the first and last matches – preferably in one pass.

I think the easiest way is to use the trick from the last article

$finds = Select-String -Path c:\test\*.txt -Pattern "\A\w{5}ABCD"

$finds[0]
$finds[-1]

The $finds variable conatins a collection of the MatchInfo objects created by Select-String.  The first match will always have the index of 0 and the last can always be referenecd by an index of -1. This information is returned:

C:\test\fixedcol.txt:1:12345ABCD123451234512345
C:\test\fixedcol.txt:6:12345ABCD123451234512345

If you want this in an object for further processing – try something like this

Get-ChildItem -Path c:\test -Filter *.txt -Recurse |
foreach {

$finds = $null
$finds = Select-String -Path $_.Fullname -Pattern "\A\w{5}ABCD"

if ($finds){
 
  $props = [ordered]@{
    Filename  = $finds[0].Path
    FirstLine = $finds[0].LineNumber
    FirstData = $finds[0].Line
    LastLine = $finds[-1].LineNumber
    LastData = $finds[-1].Line
  }
  New-Object -TypeName PSObject -Property $props
}
}

Use Get-ChildItem to find the files. For each of them run Select-String with your pattern. If you get any matches create an object holding the file path and your required properties. In this case I’m taking the first and last line numbers with the match data.

If you only have a single match in a file you will get the same data in the First* and Last* properties as the first and last match are the  same.  You could put another if statement to control this so the Last* properties aren’t populated if you want. 


January 9, 2013  11:18 AM

Workflow article 3

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

 

The next in the series of articles on PowerShell workflows that are appearing on the Scripting Guy blog has been published.

The articles in the series that have been published are:

http://blogs.technet.com/b/heyscriptingguy/archive/2012/12/26/powershell-workflows-the-basics.aspx
http://blogs.technet.com/b/heyscriptingguy/archive/2013/01/02/powershell-workflows-restrictions.aspx
http://blogs.technet.com/b/heyscriptingguy/archive/2013/01/09/powershell-workflows-nesting.aspx

Look for the next article in one weeks time.

Until then Enjoy!


January 8, 2013  3:32 PM

Select-String–information on matching files

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Following on from yesterday’s post this is the second question:

Since I’m recursively searching thru files to find matching phrases, how can I obtain other directory service information about the matching files file(s) – this is more of a methodology technique question because I realize there are multiple ways of achieving this?

You could do something like this

foreach ($find in Select-String -Path c:\test\*.txt -Pattern "\A\w{5}ABCD" -List){
Get-ChildItem -Path $find.Path
}

Run the Select-String as before but only get the first match in each file.  Use foreach to access the match information and use the Path property to feed into Get-ChildItem.

If you want things to be a bit simpler – break it down to:

$finds = Select-String -Path c:\test\*.txt -Pattern "\A\w{5}ABCD" -List
foreach ($find in $finds){
Get-ChildItem -Path $find.Path
}

Alternatively if you want the PowerShell one-liner approach try

Get-ChildItem -Path  (Select-String -Path c:\test\*.txt -Pattern "\A\w{5}ABCD" -List).Path

Personally I would probably go for the simple approach


January 7, 2013  4:41 PM

Select-String scenarios – fixed columns

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

 

I had some questions come in after mu recent post regarding select-string. I’ll answer them as a series of posts. First off:

I’m recursively searching thru many files, and want to pull out specific data in ‘fixed column’ positions from the line(s) that match the phrase I’m seeking, i.e. position 10 thru 15 of the line or  position 6 thru the end of the line (which might be unknown).
What is your preferred method for handling this situation?

I started by creating a file

12345ABCD123451234512345
1234512345ABCD1234512345
12345ABCD123451234512345
12345abcd123451234512345
123451234512345ABCD12345
12345ABCD123451234512345
123451234512345ABCD12345
12345123451234512345ABCD
1234512345ABCD1234512345

I want to pick out the string ABCD but ONLY when its in columns6-9.  A quick inspection shows I should get four lines returned.

If you go with a simple match you get all lines returned

PS> Select-String -Path c:\test\*.txt -Pattern “ABCD” -SimpleMatch

C:\test\fxedcol.txt:1:12345ABCD123451234512345
C:\test\fxedcol.txt:2:1234512345ABCD1234512345
C:\test\fxedcol.txt:3:12345ABCD123451234512345
C:\test\fxedcol.txt:4:12345abcd123451234512345
C:\test\fxedcol.txt:5:123451234512345ABCD12345
C:\test\fxedcol.txt:6:12345ABCD123451234512345
C:\test\fxedcol.txt:7:123451234512345ABCD12345
C:\test\fxedcol.txt:8:12345123451234512345ABCD
C:\test\fxedcol.txt:9:1234512345ABCD1234512345

Notice the match is case INSENSITIVE

This means we get into the world of regular expressions – joy!

This will work

Select-String -Path c:\test\*.txt -Pattern “\A.{5}ABCD”

The regular expression means match any 5 characters followed by ABCD starting at the beginning of the string.

Alternatively you could use

Select-String -Path c:\test\*.txt -Pattern “\A\w{5}ABCD”

This is the same except its accepting any word character (letter, digit, math symbol and punctuation)

These two searches are case INSENSITIVE

if you need case sensitivity then compare

Select-String -Path c:\test\*.txt -Pattern “\A\w{5}ABCD”  -CaseSensitive
Select-String -Path c:\test\*.txt -Pattern “\A\w{5}abcd”  -CaseSensitive

or

Select-String -Path c:\test\*.txt -Pattern “\A.{5}ABCD” -CaseSensitive
Select-String -Path c:\test\*.txt -Pattern “\A.{5}abcd” -CaseSensitive


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: