'Measure-Object' not working in windows powershell - how to do basic sums? - powershell

I have windows 7 at work. I don't know what version of powershell that I have, but it says it is from 2009. I have been using Google-Fu to find out how to do some basic math in powershell - sums, specific sums, etc, but what I am finding isn't working - I think it is because I am using a very old version of powershell.
For instance, this command works:
gc filename -totalcount 1000
This command does not work:
gc filename -head 1000
When I run:
gc filename Measure-Object "Column Name" -Sum
I get the error:
"Get-Content: A positional parameter cannot be found that accepts argument 'Measure-Object'.
Can anyone help? Or point me to a resource that has older commands?

You need to use the pipeline to pass one object to another command:
Get-Content filename | Measure-Object
I'd also recommend reading the documentation on Measure-Object so you know how to use it correctly.

Find your PowerShell version using this code snippet. As noted above, 2.0 is the default for Windows 7.
$PSVersionTable.PSVersion
Secondly, I highly recommend (unless you have specific version constraints) to upgrade to PowerShell 5.1 as there were some bugs in the older versions that have been fixed.
https://www.microsoft.com/en-us/download/details.aspx?id=54616
Third you likely need to do more manipulation of the file after using Get-Content before you can measure it. If it's a CSV you may need to specify the specific column you want to manipulate. If you provide more detail of what you are trying to do in a general sense, it'd be easier to provide more targeted feedback.

Related

Get-Recipient to Get-EXORecipient? Powershell and Exchange

Had a quick and hopefully easy question for you guys. I've tried googling and searching but I haven't been able to find much info.
We've been asked to try and streamline and improve some scripts we have. I was trying to convert some Get-Recipient commands to the newer and quicker Get-EXORecipient module.
I'm having some issues with the below though and would appreciate any help or advice:
As part of one of my scripts, I use the below command to find a specific DDL. This works fine
$var1 = Get-DynamicDistributionGroup -Identity "DDLName"
The issue I have is trying to get details from this DDL using the new module
Extract of old code which works but is quite time consuming depending on the size of the DDL
$var2 = Get-Recipient -RecipientPreviewFilter $var1.RecipientFilter
The new code I'm trying which spits out an error
$var2 = Get-ExoRecipient -RecipientPreviewFilter $var1.RecipientFilter
The error I get from the above is "Get-ExoRecipient : RecipientPreviewFilter is not a supported parameter"
I haven't been able to find out how to apply the DDL filter to this command, I tried putting the entire filter in as a string but that didn't work either. That wasn't an ideal solution as the filter may change on the exchange side.
Would appreciate any help on this one!
Thanks
According to the Get-EXORecipient documentation, the -RecipientPreviewFilter parameter has been reserved for 'internal Microsoft use'.
You should be able to use the -Filter parameter instead though like this:
Get-ExoRecipient -Filter "Title -eq 'Teaching Staff'"
However, the format of the filter returned by the dynamic distribution group may differ slightly and require some changes before it can be used with -Filter

Create a small file(.txt or .TMP) from a huge .TMP file

'System.OutOfMemoryException' error occured while creating a small file from big file.
I usually use the below PowerShell command to create a small version of a huge file,
Get-Content input_file_name.Tmp -TotalCount 100 | Out-File -Encoding Default "output_file_name_100.Tmp"
However, this is throwing a 'System.OutOfMemoryException' error. Any advise on this?
Note : It has worked earlier for bigger files. I think the size of the file is not the problem.
I know that you personally think the size of the file may not be the actual problem, but it's worth revisiting the fundamentals for the benefit of other readers.
Get-Content, when used in a pipeline, reads lines from a file one at a time.
This object-by-object processing is a core feature of PowerShell's pipeline and acts as a memory throttle (no need to read all input into memory at once.
There are only three scenarios where Get-Content reads the whole file into memory:
If you capture Get-Content's output in a variable ($content = Get-Content ...), in which case the variable receives an array comprising all lines.
If you enclose the Get-Content call in (...), $(...), or #(...), which also returns an array of all lines.
If you use the -Raw switch, which makes Get-Content return a single, multi-line string.
Using -TotalCount 100 (or -First 100) doesn't change this fundamental behavior: after 100 lines have been read, Get-Content stops reading and closes the file.
The code in your question therefore doesn't explain your symptom - you shouldn't run out of memory - at least not because the input file is large; if it still happens, you may be seeing a bug.
If you have a reproducible case, I encourage you to file a bug in the Windows PowerShell UserVoice forum or, if you can (also) reproduce the bug in PowerShell [Core] v6+, at the PowerShell Core GitHub repo.
In the meantime, you can consider using .NET directly, which also generally
faster than using PowerShell's cmdlets:
[Linq.Enumerable]::Take([IO.File]::ReadLines("$PWD/input_file_name.Tmp"), 100) |
Out-File -Encoding Default output_file_name_100.Tmp
Note:
• The use of "$PWD/" as part of the input file path, because .NET's working directory typically differs from PowerShell's.
• In PowerShell type literals ([...]), the System. part of the full type name can be omitted; thus [Linq.Enumerable] refers to System.Linq.Enumerable, and [IO.File] to System.IO.File

Microsoft's Consistency in PowerShell CmdLet Parameter Naming

Let's say I wrote a PowerShell script that includes this commmand:
Get-ChildItem -Recurse
But instead I wrote:
Get-ChildItem -Re
To save time. After some time passed and I upgraded my PowerShell version, Microsoft decided to add a parameter to Get-ChildItem called "-Return", that for example returns True or False depending if any items are found or not.
In that virtual scenario, do I have I to edit all my former scripts to ensure that the script will function as expected? I understand Microsoft's attempt to save my typing time, but this is my concern and therefore I will probably always try to write the complete parameter name.
Unless of course you know something I don't. Thank you for your insight!
This sounds more like a rant than a question, but to answer:
In that virtual scenario, do I have I to edit all my former scripts to ensure that the script will function as expected?
Yes!
You should always use the full parameter names in scripts (or any other snippet of reusable code).
Automatic resolution of partial parameter names, aliases and other shortcuts are great for convenience when using PowerShell interactively. It lets us fire up powershell.exe and do:
ls -re *.ps1|% FullName
when we want to find the path to all scripts in the profile. Great for exploration!
But if I were to incorporate that functionality into a script I would do:
Get-ChildItem -Path $Home -Filter *.ps1 -Recurse |Select-Object -ExpandProperty FullName
not just for the reasons you mentioned, but also for consistency and readability - if a colleague of mine comes along and maybe isn't familiar with the shortcuts I'm using, he'll still be able to discern the meaning and expected output from the pipeline.
Note: There are currently three open issues on GitHub to add warning rules for this in PSScriptAnalyzer - I'm sure the project maintainers would love a hand with this :-)

Powershell dot notation not selecting data

I'm having a problem getting Powershell to behave the way I'm expecting.
I'm trying to use get-wmiobject win32_networkconnection to list the mapped drives for the current user, so I can loop through the drives.
When I run $var = get-wmiobject win32_networkconnection | select -expand localname I get exactly what I expect: a list of the drive letters for the mapped network connections.
However, when I run $var = (get-wmiobject win32_networkconnection).localname I get nothing. It doesn't seem to be selecting the property correctly.
This is problematic, because, ideally, I'd like to loop over all the drives, and then select the various properties for each drive. Instead, it seems like I'll be forced to kludge together an iterator, and then iterate over all the variables one at a time (not very elegant, in my opinion).
I'm not super experienced with Powershell, so there may be something I'm missing. However, from what I've read, this should be working. Is this a limitation of get-wmiobject?
What you're trying to do only works in PowerShell 3.0 and newer versions. The official documentation is very vague:
What's New in Windows PowerShell 3.0
Windows PowerShell Language Enhancements
Windows PowerShell 3.0
includes many features [...] The improvements include
property enumeration, count and length properties on scalar objects,
new redirection operators [...]
This blog post goes a bit more into depth: New V3 Language Features
Yes, this is a limitation of PowerShell 2.0.
Your call to Get-WmiObject is returning an array. In PS2, you would need to pipe the array into something like Select-Object or otherwise iterate over it and reference each individual item.
In PS3+, you can use $array.PropertyName and it does that for you, returning an array of properties.
intead of select propertyName, you can use select -exp propertyName

PowerShell File Sorting

So I feel like PS would be the best solution for this project, but cannot for the life of me figure out where to get started with it, here's the file layout..
I've got one folder, filled with folders generated by our automated system, they are labeled: foobarXXXXXXXXXXXXXXX
The end 15 characters of the folder is what I need to grab, and then search through another folder for any files that contain those 15 characters, and then move any files found into their respective folders.
I can give more details if this wasn't sufficient. Just need a point to get started.
I'm running Windows 7 should the version of PowerShell be a concern.
Ideally you want Powershell 3, but you can accomplish this task in Powershell 2 as well.
I would first look into the Select-String cmdlet. Also found on technet here.
It is also perfectly legal to use SubString function for .NET string manipulation.
$filePattern = $string.Substring(1,15)
To get collections of your files, you should use Get-ChildItem. Using the "#" in "#(Get-ChildItem)" produces an explicit array.
$files = #(Get-ChildItem -Path $path -Recurse)
And since there is no specific detail in your question there are no specific answers.
Also, I run Windows 7 with Powershell 2 and 3, side by side. Powershell 3 is kinda awesome.