Get-content from txt, skip rows and first character with substring

Trying to get-content from txt and remove some of the content on the way but it fails with:
Exception calling “Substring” with “1” argument(s): “startIndex cannot be larger than length of string.
Parameter name: startIndex”
At line:1 char:1

  • $substring = $a.Substring(2)
  •   + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
      + FullyQualifiedErrorId : ArgumentOutOfRangeException
    
    

It works on a txt file with fewer character, with: $substring = $a.Substring(2).

On the txt file were it doesn’t work contains more characters and that case I want to remove the first 20 character.

Edit: it seems it won’t work to skip these characters with substring: … -------
If I remove those manually and have “KB2267602” in the beginning of the txt - it works.

Hi, welcome to the forum :wave:

Can you provide some more detail about what you’re actually trying to do?

On the face of it, it sounds like the wrong approach (a case for Select-String instead?) but we need more context.

If posting code in your reply, please can you use the </> button to format it properly. If you can’t see the button in the toolbar, it will be under the gear icon.

How to format code on PowerShell.org

Thank you :slight_smile:

I’m trying to get content from a txt to a variable and then want to cut some content of it.

$a = get-content -Path 'C:\Scripts\updates.txt' | Select -Skip 3
$substring = $a.Substring(2)

How does your input file updates.txt look like and what output would you expect? Assuming your input file has more than just 4 lines (with Select -Skip 3 you skip the first 3 lines!! :smirk: ) , $a and therefor $substring will still be arrays - not just a single string.

(When you post sample data or error messages you should format them as code as well. :point_up:t3:)

You may explain as well what the actual complete task is - not the step you think you need to go to get to the result you need. The bigger picture … there may be another/better way. Since PowerShell works with objects and properties it is most of the times unnecessary to do extensive string acrobatics. :point_up:t3: :wink:

1 Like

updates.txt look like this


ComputerName Status     KB          Size Title                                                    
------------ ------     --          ---- -----                                                    
hostname... -------    KB2267602 1008MB Security Intelligence Update for Microsoft Defender An...
hostname... -------                17KB DTS - SoftwareComponent - 1.10.5.0                       

I want to skip the ComputerName Status etc and hostname… -------

:slight_smile:

It might be helpful to provide the example file for us so we aren’t guessing, and share with us the exact output you desire (instead of describing it), as I am still not quite clear on the ask. Could you clarify what you want to skip? The output looks like a table. if they were a table, are you not wanting the headers or the entire columns? I see you want to skip ComputerName, Status, ‘etc’ and hostname, but hostname is clearly under computer name so it seems like you want to get rid of that entire ‘column’. Is that correct? All of this stuff matters :slight_smile:

Also the txt file you are importing, is it actually a CSV just stored as a txt file? If so, it might be easier to to work with the data if you import it as a CSV (and probably just store it as a csv). Working with data imported from a CSV, IMO, is a little easier to work with especially if trying to omit ‘columns’.

This looks like the ouptut from a PowerShell command piped to a txt file. How do you populate this file? As I already mentioned PowerShell works with objects and properties. In the vast majority of the cases there’s no need to parse text or strings.

For example:
With

$UpdateList = Get-Hotfix

You save the list of installed updates in a variable named UpdateList. The output would look something like this …

Source        Description      HotFixID      InstalledBy          InstalledOn
------        -----------      --------      -----------          -----------
NUC12PRO      Update           KB5034466     NT AUTHORITY\SYSTEM  14.02.2024 00:00:00
NUC12PRO      Update           KB5027122     NT AUTHORITY\SYSTEM  13.06.2023 00:00:00
NUC12PRO      Update           KB5011048     NT AUTHORITY\SYSTEM  28.06.2023 00:00:00
...
...

But if you’re only interested in the HotfixIDs you could do this:

$UpdateList.HotFixID

And the output looks like this:

KB5034466
KB5027122
KB5011048
...
...

:man_shrugging:t3:

So … the better you describe your situation and your goal the better we can help.

Ok.
I have a schedule task that runs this script every day:

winupdate.ps1

get-windowsupdate > C:\Scripts\updates.txt

That’s it. Then I want to output the content of updates.
The rest of the script isn’t done yet. I’m in a testing phase with the code further up.
One thought was to make a windows 11 notification of the updates and then I want to remove some unnecessary text. It’s probably possible to list the updates with PSWindowsUpdate but a lot of the commands is pretty slow so I want it in a text file with updates every day.

Hi @user1010

Let’s try one last time. Can you please answer the questions folks are asking? I’ll write them again in the list below. You are talking about removing stuff in one post, now you’re talking about notifications, originally you were talking about substrings. We need to understand what you are trying to accomplish. If you’re not sure what you want, pick one thing you think you want and we can start there. Be very explicit, make 0 assumptions about what you think we might know. Do not be vague, do not leave things out. We don’t know what output you want, you have to tell us, you can’t just tell us you want ‘content of updates’ You can’t just tell us ‘unnecessary text’, as we don’t know what that means for your project. You have to help us help you.

  1. What’s your end goal look like, show the output you want, literally. Tell us in very clear concise manner what you want to do, then provide an example of it. What unnecessary text? Be very very specific and show us an example. Don’t say ‘etc.’ because we don’t what etc.’ means in the context of what you are trying to accomplish.
  2. Show us the code of Get-WindowsUpdate or winupdate.ps1. We don’t know what your code is calling to get the data. Show us how you are populating that text file. Get-WindowsUpdate isn’t a cmdlet that I’m aware of, so you’ll need to tell us what module that’s form or what it is. Be very clear. We want all the details. Share with us the code, formatted. If we understand how you’re getting the initial data, and explicitly what you want that data to look like after manipulating it, we can likely assist you in getting from point A to point B.

As Olaf mentioned, PS is an object oriented language. It’s easy to work with objects. Olaf already provided some examples of how you can work with a PS Object. For example if you had the content as a proper object, you could filter out columns (or properties as they are in PS) very easily with Select-Object. However, Select-Object isn’t going to work that great using Get-Content, as the thing you are geting back is essentially an object of strings. You can loop through them, you can select only some of the lines (rows). That might mean you should adjust your original script and output it in a different manner so you can more easily filter on it. You can certainly parse text and do a ton of replaces etc. but it’s generally not necessary if you approach the problem in a different way.

Lastly, if the output of your Get-WindowsUpdate command is throwing a PS object into a text file, you should try to use Export-CSV instead if it’s absolutely necessary to output the data into the file. You then can use Import-CSV to pull it in and have an easier object to work with. Non the less it’s likely possible you can skip all of that and just have code to do it all as part of the scheduled task.

1 Like

Ok. I’ll try again.

I have installed this module: PowerShell Gallery | PSWindowsUpdate 2.2.0.3

With the PSWindowsUpdate module I add info to C:\Scripts\updates.txt with this schedule task:

winupdate.ps1

get-windowsupdate > C:\Scripts\updates.txt

updates.txt contains this:

ComputerName Status KB Size Title


hostname… ------- KB2267602 1008MB Security Intelligence Update for Microsoft Defender An…
hostname… ------- 17KB DTS - SoftwareComponent - 1.10.5.0

When I use Get-Content and updates.txt I want to remove:

ComputerName Status KB Size Title


and also want to remove:
hostname… -------

The code I have tested for this is in my command history in powershell:
$a = get-content -Path ‘C:\Scripts\updates.txt’ | Select -Skip 3
$substring = $a.Substring(2)
$substring

Do you understand what I mean?

Again: PowerShell works with objects and properties. And if you just need particular properties of an object you can specify them. That’s better than removing them later on. If you don’t need hostname and status don’t get it. If you don’t need the table headers don’t get it. :man_shrugging:t3:

Get-WindowsUpdate | 
    Format-Table -HideTableHeaders -Property KB, Size, Title | 
        Out-File -FilePath C:\Scripts\updates.txt

Please format your code as code.

With $a.Substring(2) you output the string contained in the variable $a without its first 2 characters!!

BTW: I’d consider the module you picked at least very weird. It does not output the properties you would expect. So you cannot use Select-Object on them.

You - again - only explained the step you think you need to go to come to where you want. We still only have vague clue on what you actually want to achieve.

If I got it right you’re overcomplicating this a lot. And you definitely do NOT need to write a text file you parse later on. :man_shrugging:t3:

1 Like

Works good :slight_smile:
I didn’t think about you could do that directly with the module.

The only more thing I was thinking about is to create a notification with BurntToast (Create pop-up notifications from PowerShell with BurntToast). After installation, that can be done with:

New-BurntToastNotification -text "$a" 

Maybe :wink:

How long would it take you to think about? :smirk:

$a = Get-WindowsUpdate | 
    Format-Table -HideTableHeaders  -Property KB, Size, Title | 
        Out-String
New-BurntToastNotification -Text $a

Very nice :slight_smile:
Works for me.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.