Adding user input to a Select-String command - powershell

I'm currently trying to create a select-string command to determine if users in my company are still showing up in certain directories. My current command is a follows:
Select-String -path "C:\filepath\*.csv" -Pattern "<string>" |
Format-Table -Property LineNumber,Line,Path -Wrap |
Out-File "C:\outfile.txt"
The current command means I'd need to alter the content of the Pattern parameter each time before running the script. What I'd like to do instead is to request my input for the string when I run the script. Is there a while loop I can add to this command to request user input?
Thanks

Add this to the head of your script:
Param(
[Parameter(Mandatory = $True)]
[System.String]
$Pattern
)
Select-String -Path C:\filepath\*.csv -Pattern $Pattern |
Tee-Object -FilePath C:\outfile.txt |
Format-Table -Property LineNumber, Line, Path -Wrap
When you call the script, the attribute makes sure you give an argument to -Pattern. You can add further attributes if you want this to not be null ([ValidateNotNullOrEmpty()]), etc.
As an aside, never pipe from formatters.

Related

Remove blank space from text file

I have a script to import the names of the virtual machines from hyper-v to a txt file.
The problem is that sometimes the names have blank spaces on the back, and when I try to turn them off or on with the script it does not find those machines because of the blank spaces.
Any way to remove the blank spaces from the file?
$vm = Get-VM | select name | Out-File -FilePath $ListVM
(Get-Content $ListVM | Select-Object -Skip 3) | ? {$_.trim() -ne ""} | Set-Content $ListVM
Withstanding Santiago's relevant alternate comment/approach. the cause of your issue may be:
Generally the Out-* cmdlets will force objects through PowerShell's for-display formatting system. You can use Set-Content from the start to avoid this, however you cannot simply select the name property doing so will create objects with the single property named "name". When Set-Content sees that it will write hash/object syntax to the file trying to represent the object, like:
#{Name=MachineName}
To avoid this simply expand the property you want to store in the file:
Get-VM |
Select-Object -ExpandProperty Name |
Set-Content -FilePath $ListVM
Or:
(Get-VM).Name | Set-Content -FilePath $ListVM
Note: you are assigning $VM to the output, however that will result in $VM being null. I'm not sure what the intent is, but if you want the resulting list stored in the variable add the -PassThru parameter like:
$vm = (Get-VM).Name | Set-Content -FilePath $ListVM -PassThru

Powershell script to compare processes from text file

I need to do the following:
Get a list of all the current processes on the system and save them to a text file called “before.txt”
Launch a new browser window (Chrome, Edge, Firefox – your choice)
Get a new list of all the current processes on the system and save them to a text file called “after.txt”
Using the compare-object cmdlet in PowerShell, find the new process ID for the browser you just opened
Once the process ID has been identified, kill the process using that process ID
I'm having difficulty completing the last task of killing the identified process from the text file. Any help is greatly appreciated. Thank you!
########################## Current Script#########################
Get-Process | select-object -Expand Name > before.txt
Invoke-Item "C:\Program Files\Internet Explorer\iexplore.exe"
Start-Sleep -s 3
Get-Process | select-object -Expand Name > after.txt
Compare-Object (get-content before.txt) (Get-Content after.txt) > final.text
$list = Get-Content final.text; Get-Process $list | kill -force -Raw
The simple fix to your code is to change the compare-object line. Try running that line without the redirect and you'll see it's not a simple list of names. Try changing that line in your script to the following:
Compare-Object (get-content before.txt) (Get-Content after.txt) | select -ExpandProperty InputObject > final.text
However, in PowerShell you don't need to use all these temporary files. You can have arrays of items. A more PowerShell answer would be:
$before = Get-Process
Invoke-Item ...
$after = Get-Process
$list = Compare-Object $before $after
$list |% { stop-process $_.InputObject.id }

Out-file , txt are created , no data saved [duplicate]

I'm new to scripting and I am trying to write the information returned about a VM to a text file. My script looks like this:
Connect-VIServer -Server 192.168.255.255 -Protocol https -User xxxx -Password XXXXXX
Get-VM -Name xxxxxx
Get-VM xxxxx | Get-HardDisk | Select Parent, Name, Filename, DiskType, Persistence | FT -AutoSize
Out-File -FilePath C:Filepath
I am able to connect to the VM, retrieve the HDD info and see it in the console. The file is created where I want it and is correctly named. No data is ever put into the file. I have tried Tee-Object with the same results. I've also tried the -append switch. I did see a post about the data being returned as an array and Powershell is not able to move the data from an array to a string. Do I need to create a variable to hold the returned data and write to file from there?
Thanks
Guenther Schmitz' answer is effective, but it's worth explaining why:
Your Out-File -FilePath C:Filepath is a stand-alone command that receives no input.
An Out-File call with no input simply creates an empty file (0 bytes).
In order for cmdlets such as Out-File to receive input from (an)other command(s) (represented as ... below), you must use the pipeline, which means that you must place a | after the input command(s) and follow it with your Out-File call:Note that I'm using the shorter -Path parameter alias for the less commonly used -FilePath[1]
... | Out-File -Path C:Filepath
In the simplest case, as above, the entire command (pipeline) is placed on the same line; if you want to spread it across multiple lines for readability, you have have two choices:
Put a line break immediately after |, which tells PowerShell that the command continues on the next line:
... |
Out-File -Path C:Filepath
End a line with an explicit line continuation, which means placing ` at the very end of a line:
... `
| Out-File -Path C:Filepath
Alternatively, since you're using Out-File with its default behavior, you could use >, an output redirection, instead:
... > C:Filepath
A couple of asides:
Using Out-File with something other than strings, and using Format-* cmdlets in general, means that the output is only suitable for display (human consumption), not for further programmatic processing.
If you want to send output to both the console and a file, use the Tee-Object cmdlet, as TobyU suggests:
... | Tee-Object -Path C:Filepath
[1] Strictly speaking, -LiteralPath is the best choice in this case, because -Path interprets its arguments as wildcard expressions. However, omitting -Path, i.e. specifying the file path as a positional argument, as is common, implicitly binds to -Path.
try this:
Get-VM xxxxx |
Get-HardDisk |
Select Parent, Name, Filename, DiskType, Persistence |
Out-File -FilePath C:\Filepath

Writing console output to a file - file is unexpectedly empty

I'm new to scripting and I am trying to write the information returned about a VM to a text file. My script looks like this:
Connect-VIServer -Server 192.168.255.255 -Protocol https -User xxxx -Password XXXXXX
Get-VM -Name xxxxxx
Get-VM xxxxx | Get-HardDisk | Select Parent, Name, Filename, DiskType, Persistence | FT -AutoSize
Out-File -FilePath C:Filepath
I am able to connect to the VM, retrieve the HDD info and see it in the console. The file is created where I want it and is correctly named. No data is ever put into the file. I have tried Tee-Object with the same results. I've also tried the -append switch. I did see a post about the data being returned as an array and Powershell is not able to move the data from an array to a string. Do I need to create a variable to hold the returned data and write to file from there?
Thanks
Guenther Schmitz' answer is effective, but it's worth explaining why:
Your Out-File -FilePath C:Filepath is a stand-alone command that receives no input.
An Out-File call with no input simply creates an empty file (0 bytes).
In order for cmdlets such as Out-File to receive input from (an)other command(s) (represented as ... below), you must use the pipeline, which means that you must place a | after the input command(s) and follow it with your Out-File call:Note that I'm using the shorter -Path parameter alias for the less commonly used -FilePath[1]
... | Out-File -Path C:Filepath
In the simplest case, as above, the entire command (pipeline) is placed on the same line; if you want to spread it across multiple lines for readability, you have have two choices:
Put a line break immediately after |, which tells PowerShell that the command continues on the next line:
... |
Out-File -Path C:Filepath
End a line with an explicit line continuation, which means placing ` at the very end of a line:
... `
| Out-File -Path C:Filepath
Alternatively, since you're using Out-File with its default behavior, you could use >, an output redirection, instead:
... > C:Filepath
A couple of asides:
Using Out-File with something other than strings, and using Format-* cmdlets in general, means that the output is only suitable for display (human consumption), not for further programmatic processing.
If you want to send output to both the console and a file, use the Tee-Object cmdlet, as TobyU suggests:
... | Tee-Object -Path C:Filepath
[1] Strictly speaking, -LiteralPath is the best choice in this case, because -Path interprets its arguments as wildcard expressions. However, omitting -Path, i.e. specifying the file path as a positional argument, as is common, implicitly binds to -Path.
try this:
Get-VM xxxxx |
Get-HardDisk |
Select Parent, Name, Filename, DiskType, Persistence |
Out-File -FilePath C:\Filepath

Select-Object omitting output from Select-String powershell

I wrote a Powershell script that looks for a string (such as ERROR) in log files and grabs those lines and outputs those lines to a file, for simpler reading and such (the industry I'm in has VERY large log files), but I'm having an issue. Before, when the (relevant) part of the code looked like this:
Select-String -Path "$file" -Pattern "$string" -CaseSensitive | Out-File -filepath $filepath
It would output the file path, the line number, and then the actual line, making for a very cluttered file. Well I only needed the line and the line number, so I did this:
Select-String -Path "$file" -Pattern "$string" -CaseSensitive | Select-Object -Property LineNumber,Line | Out-File -filepath $filepath
Which would return lines looking like this:
978 2017-07-10 10:46:11,288 ERROR [Music...
That is the line number then the line, with the line only totaling 35 characters.
Before I piped Select-String to Select-Object, the script would output the whole line, but now with Select-Object it omits some output. I tried adding -verbose parameters to both Select-String and Select-Object, but that did nothing.
Can you try this :
Select-String -Path "test.xml" -Pattern "ERROR" -CaseSensitive | ft -Property LineNumber,Line -Wrap | Out-File -FilePath c:\out.txt
The reason for your problem is screen buffer length(increasing powershell screen buffer width) ,you can change it as well but the above snippet is simpler and effective