Running 2 commands separately return different output than when run together

Hi everyone,

I’m having a strange situation when creating some statistics:

  • consider a folder with log files
  • I need to create 2 reports:
  • 1st report: get the year and month when the files were last written to, group them and show the count of the files
  • 2nd report: get the first 2 characters of each file name, group the results and show the count
    In this example I only included 11 files, but my folder has a few thousands.

These are the names of the files:
Name

BHD4WF6G.log
BYL0085W.log
BYL0093G.log
BYL0226G.log
BYL0268G.log
HHD0012G.log
LUL7N4ZG.log
SUL6506G.log
TSLBPUKG.log
UUL6PZWG.log
UUL8PZ3G.log

And here are my commands:

$List = Dir "D:\Logs" -Filter *.log

$List | ForEach-Object {Get-Date -Format "yyyy-MM" ($_.LastWriteTime)} | Group-Object | Select @{Label='Month';Expression={$_.Name}},@{Label='IPU attempts';Expression={$_.Count}} | Sort Month -Descending
$List | ForEach-Object {($_.Name)[0..1] -join ""} | Group-Object | Select @{Label='Location Code';Expression={$_.Name}},@{Label='IPU attempts';Expression={$_.Count}} | Sort 'Location Code'

When running the last 2 commands individually, I get the expected result (column headers and correct info):

When I select both commands and execute them together, the last one does not generate column headers and also the ‘Location Code’ column is empty.
I’m having problems understanding why.

Powershell does a lot of “optimization” for you under the hood. And sometimes it does a little bit too much. I assume you want to output the results only to the console anyway, right? You could use a format cmdlet to output the results like you want it.

$List |
ForEach-Object {Get-Date -Format “yyyy-MM” ($.LastWriteTime)} |
Group-Object |
Select-Object -Property @{Label = ‘Month’; Expression = {$
.Name}}, @{Label = ‘IPU attempts’; Expression = {$_.Count}} |
Sort-Object -Property Month -Descending |
Format-Table

$List |
ForEach-Object {($.Name)[0…1] -join “”} |
Group-Object |
Select-Object -Property @{Label = ‘Location Code’; Expression = {$
.Name}}, @{Label = ‘IPU attempts’; Expression = {$_.Count}} |
Sort-Object -Property ‘Location Code’ |
Format-Table

Yes, Format-Table did the trick! Thanks a lot!

Powershell is implicitly sending two different objects to format-table, but format-table can only display one set of columns. Unless there is a format file that tells how to display the first object. Here’s an odd workaround where you put get-date at the beginning of the script. Explicitly running format-table more than once is another workaround. If there were 5 properties in the first object, it would implicitly go to format-list and wouldn’t be a problem.

[pscustomobject]@{name = 'Joe'; address = 'Here'}
[pscustomobject]@{name = 'Joe'; phone = '8675309'}

name address
---- -------
Joe  Here
Joe


get-date
[pscustomobject]@{name = 'Joe'; address = 'Here'}
[pscustomobject]@{name = 'Joe'; phone = '8675309'}

Monday, March 11, 2019 9:48:54 AM

name    : Joe
address : Here

name  : Joe
phone : 8675309
[pscustomobject]@{name = 'Joe'; address = 'Here'; phone='123'; street = 'johnson'; town='springfield'}
[pscustomobject]@{name = 'Joe'; phone = '8675309'; address = 'here'; extra = 'this'};


name    : Joe
address : Here
phone   : 123
street  : johnson
town    : springfield

name    : Joe
phone   : 8675309
address : here
extra   : this