how to search a file order output in powershell - powershell

I have a text file called "file.txt" with an output like below
Ethernet4
vEthernet
Ethernet
Ethernet
Public
Is there any methord in powershell to check , whether the name vEthernet is first in order of the output file ?

To extract the first element of an array you can use the brackets with 0 [0] like that :
$myArray = #('Ethernet4', 'vEthernet', 'Ethernet', 'Ethernet', 'Public')
$myArray[0]
so if you want to test the first element, you can use a if :
if($myArray[0] -eq 'vEthernet') {
Write-Host 'YES'
} else {
Write-Host 'NO'
}
Better answer for your particular problem :
Since your input comes from a file, if you need to read only the first line and not more :
$result = Get-Content -Path '.\file.txt' -TotalCount 1
if($result -eq 'vEthernet') {
Write-Host 'YES'
} else {
Write-Host 'NO'
}

Related

Powershell - Fix Line Break

I have a situation here and I would like to share it with you to ask for help.
I have a TXT file that I receive every day and I need to import it into my ERP, however, this file comes with a line break that we have to manually adjust
And when adjusted, it looks like this:
{
Write-Error "Informe um arquivo para leitura"
Return
}
$arquivo = $args[0]
if(![System.IO.File]::Exists($arquivo))
{
Write-Error "Arquivo nao encontrado: $arquivo"
Return
}
$tamanhoEsperado = 240
$ultimoTamanho = 0
foreach($linha in [System.IO.File]::ReadLines($arquivo))
{
if ($linha.length -gt 0)
{
if (!($linha.length -eq $tamanhoEsperado) -And (($linha.length + $ultimoTamanho) -eq $tamanhoEsperado))
{
Write-Host -NoNewLine $linha
$ultimoTamanho += $linha.length
}
else
{
if ($ultimoTamanho -gt 0)
{
Write-Host
}
Write-Host -NoNewLine $linha
$ultimoTamanho = $linha.length
}
}
else
{
Write-Host
}
}
But I am not able to make the process automatic with this script.
Powershell will look for the TXT file in a specific folder, validate if the file has 240 positions and if not, correct that line break shown in img1. Would that be possible?
Note:
Write-Host is typically the wrong tool to use, unless the intent is to write to the display only, bypassing the success output stream and with it the ability to send output to other commands, capture it in a variable, or redirect it to a file. To output a value, use it by itself; e.g., $value instead of Write-Host $value (or use Write-Output $value). See this answer for more information.
Therefore, your code only produced for-display output, not data.
Try something like the following:
$fragment = ''
$correctedLines =
foreach ($line in [System.IO.File]::ReadLines($arquivo)) {
if ($fragment) { # The previous line was incomplete.
$fragment + $line # Concatenate the fragment with the current line and output.
$fragment = '' # Reset the fragment variable.
} elseif ($line.Length -ne 240) {
$fragment = $line # Save the fragment and continue.
} else {
$line # Complete line -> output it.
}
}
Note the use of implicit output (e.g., $line) and that you can directly collect all output from the foreach statement in a variable.

PowerShell Isn't Parsing Data as Expected // Basic PowerShell Operator Question

I have a pretty nooby question regarding the proper usage of certain operators.
I am writing a script that pulls data out of a CSV. The script asks the user to enter a location # and then is supposed to output the IP of their server.
The script works as expected except on rows where the location number also has other text in it like numbers or special characters.
Here is an example CSV to illustrate my problem:
Loc#,State,Server IP
1,NY,10.0.0.1
2,CA,10.0.0.2
3,WA,10.0.0.3
4 (inp),KY,10.0.0.4
My script looks something like this:
$CSV = import-csv C:\users\Self\MyProject.csv
$location = read-host "enter the location #"
foreach( $row in $CSV){
if($row.loc# -eq $location)
{
write-host $row.'Server IP'
}
Now, this script works as expected unless the user chooses location 4. If the users chooses location 4, then the $location variable is left blank.
Ok, this makes a little bit of sense since I'm using the -eq operator. But even if I use the -contains operator I get the same results.
Here is another way of showing my problem:
$number = "10 ten"
if ($number -contains "10"){ (Write-Host "true")} else{ write-host "false"}
false
Now, why isn't the output showing as "true" since that $number variable does indeed contain "10"?
Any help is much appreciated,
Thanks
As it seems, Location can have a random value and not only digits, normally you could use -match as Mahmoud Moawad pointed out in his comment, however this could also bring you problems since there is no specific pattern you can follow there is also no clear way of how you can filter the specific value. What I would personally do is give the user a list where he can choose the Location by Index:
$csv = Import-Csv C:\users\Self\MyProject.csv
$csv.foreach({
begin
{
'- Choose a location:'
$i = 0
$map = #{}
}
process
{
$map[(++$i)] = $_
"[$i] - {0}" -f $_.'Loc#'
}
})
$question = { Read-Host 'Index' }
while($true)
{
$index = (& $question) -as [int]
if($index -ge 1 -and $index -le $csv.Count)
{
break
}
'Input must be between 1 and {0}!!' -f $csv.Count
}
$map[$index].'Server IP'
As for why -contains is not showing you $true on your condition, the Containment Operators will look for an exact match of an element:
'10 ten' -contains '10' # => False
'10 ten' -contains '10 ten' # => True
'9 nine', '10 ten' -contains '10 ten' # => True

Nested foreach loop in powershell

I am trying to read the values from file abc.txt in below function
abc.txt
a=abcdef123
b=ngh567
c=defh123
Below is the function:
function List
{
Write-Output "Below are the window boxes"
$alph = #(get-content -Path "abc.txt" | %{$_.split('=')[0]})
$machinelist = #(get-content -Path "abc.txt" | %{$_.split('=')[1]})
$counter = 0
foreach ($mac in $machinelist) {
foreach ($env in $alph ) {
{
$counter++
write-host ""$counter": Press '"$counter"' to select "$env": $mac"
}
}
}
I want the input similar to
1: Press '1' to select a : abcdef123
2: Press '2' to select b : ngh567
3: Press '3' to select c : defh123
Please make a selection:
I think we need to use nested foreach but not sure what am I doing wrong
Once I make the selection for e.g. 1 then I want read the value like env and mac
You cross-posted this same query to another site, that I responded to you on. That's fine, but make sure you alert and post back to sites you used when you find and accept an answer provided so that others can follow if they have such a use case.
You also change what you said you were after and even here you are not being as clear as you were on the other site.
You are still over complicating this use case, due to the experience curve. We all have to go through that, but resolve that through resource review/training. Guessing just leads to disappointment, errors, bad code, bad habits, etc.
What I gave you on the other sites, examples and such, should have gotten you to your results, yet, here I'll give this.
As for your post here. You do not need nested loops for this basic console menu effort, or all those additional split items. You can do this all in line, this way. Yet, note there are many ways to do X or Y, this is just one.
#'
a=abcdef123
b=ngh567
c=defh123
'# | Out-File -FilePath 'D:\temp\abc.txt'
Get-Content -Path 'D:\temp\abc.txt'
function Start-MenuList
{
$counter = 0
"Below are the window boxes`n"
Get-Content -Path 'D:\temp\abc.txt' |
ForEach {
$counter++
"$counter : Press $counter to select $(($PSItem -split '=')[0]) : $(($PSItem -split '=')[1])"
}
Read-Host -Prompt "`nPlease enter a selection"
}
Clear-Host
Start-MenuList
<#
# Results
Below are the window boxes
1 : Press 1 to select a : abcdef123
2 : Press 2 to select b : ngh567
3 : Press 3 to select c : defh123
Please enter a selection:
#>
There is no need for nesting loops in your case; it's sufficient to create a nested array, i.e. an array of subarrays of two elements each:
# Get the array of value pairs from the file.
# Each array element will be a subarray of 2 elements, namely
# the tokens before and after the "=".
$valuePairs = (Get-Content abc.txt).ForEach({ , ($_ -split '=') })
# Display the menu options, one for each pair.
$i = 0; $valuePairs.ForEach({ ++$i; "${i}: $($_[0]): $($_[1])" })
# Prompt the user to choose one option.
do {
try { [int] $chosenNdx = Read-Host 'Enter an index to select' } catch { }
} while (-not ($chosenNdx -in 1..($valuePairs.Count)))
# Display the chosen value pair:
--$chosenNdx # Entry was 1-based, subtract 1.
"You chose: $($valuePairs[$chosenNdx][0]): $($valuePairs[$chosenNdx][1])"

check csv for blank fields and write output if exist blank

This is a csv example:
1- 2018-11-07,hostname-184,IP_INFO, 10.2334.40.334, 255.255.255.0,
2 - 2018-11-07,hostname-184,IP_INFO, 334.204.334.68, 255.255.255.0,
3- 2018-11-07,hostname,7.1.79-8,IP_INFO, 142.334.89.3342, 255.255.255.0,
4- 2018-11-07,hostname,7.1.80-7,IP_INFO, 13342.221.334.87, 255.255.255.0,
5- 2018-11-07,hostname-155,IP_INFO, 142.2334.92.212, 255.255.255.0,
6 - 2018-11-07,hostname-184,IP_INFO, , , 1
7- 2018-11-07,hostname-184,IP_INFO, 10.19334.60.3343, 255.255.255.0,
so how can i check if the las two spaces are in blank (like line 6 ) ?
The idea is to use something like this:
$contentdnsparsed = Get-Content $destination_RAW_NAS\DNS_NAS_PARSED_0
For($i=0;$i -lt $contentdnsparsed.count;$i++){
if($contentdnsparsed[$i] -match "running")
{
$Global:MatchDNS = $OK } Else {$Global:MatchDNS = $FAIL }
}
If match "something" in the space 4 and 5 after the "," output = OK else = FAIL.
Thank you guys
Although you give us a rather bad example of a CSV file, you should use the Import-Csv cmdlet.
Because the csv has no headers, you need to supply these with the -Header parameter like below:
$csvContent = Import-Csv -Path "$destination_RAW_NAS\DNS_NAS_PARSED_0" -Header #("Date","HostName", "InfoType","IPAddress","Subnet")
$csvContent | ForEach-Object {
# test for empty IPAddress fields in the CSV
if ([string]::IsNullOrEmpty($_.IPAddress)) {
Write-Host "$($_.HostName) = FAIL" -ForegroundColor Red
# somewhere in your code you have declared the variables $Global:MatchDNS, $FAIL and $OK I guess..
$Global:MatchDNS = $FAIL
}
else {
Write-Host "$($_.HostName) = OK" -ForegroundColor Green
$Global:MatchDNS = $OK
}
}
Hope that helps

Format-Table not displaying in function

I have a section of PowerShell code that reads a list of items from Azure, and formats them into a table for the user to choose from:
if ($SubscriptionArray.Count -eq 1) {
$SelectedSub = 1
}
# Get SubscriptionID if one isn't provided
while ($SelectedSub -gt $SubscriptionArray.Count -or $SelectedSub -lt 1) {
Write-host "Please select a subscription from the list below"
$SubscriptionArray | Select-Object "#", Id, Name | Format-Table
try {
$SelectedSub = Read-Host "Please enter a selection from 1 to $($SubscriptionArray.count)"
}
catch {
Write-Warning -Message 'Invalid option, please try again.'
}
}
When executed in the main area of the script, this outputs the expected result:
I want to use this logic multiple times, and therefore moved it into a method:
function Get-IndexNumberFromArray(
[Parameter(Mandatory = $True)]
[array]$selectArray,
[Parameter(Mandatory = $True)]
[string]$message
) {
[int]$SelectedIndex = 0
# use the current subscription if there is only one subscription available
if ($selectArray.Count -eq 1) {
$SelectedIndex = 1
}
# Get SubscriptionID if one isn't provided
while ($SelectedIndex -gt $selectArray.Count -or $SelectedIndex -lt 1) {
Write-Host "$message"
$selectArray | Select-Object "#", Id, Name | Format-Table
try {
$SelectedIndex = Read-Host "Please enter a selection from 1 to $($selectArray.count)"
}
catch {
Write-Warning -Message 'Invalid option, please try again.'
}
}
return $SelectedIndex
}
Everything in this method works great, except now my table is no longer outputting to the window. Instead, the user just get a prompt to pick a number from 1 to x with no context for what each number represents.
Why is the table working in the main area of the script, but not working in a function?
Format-Table actually doesn't print a table, it outputs objects that are then printed as the table. So if you're using a function, then the Format-Table output gets part of the return value of your function.
You can add Out-Host to the pipeline to force Format-Table's result to end up on the host, i.e. the console:
$selectArray | Select-Object "#", Id, Name | Format-Table | Out-Host