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
Related
I'm working with a CSV with 5 Columns, One of the Columns has unique Values.
Fruit, Number, Car, item, color
apple, 2, Chevy, ball, blue
apple, 1, Ford, ball, green
orange, 3, Ford, string, "red,green"
orange, 5, Mazda, key, red
Banana, 4, Tesla, desk, yellow
I need to search for 3 and have it return orange ford string "red,green" as their own variable
i.e. $fruit1 becomes orange $car1 becomes ford $item becomes string and $color bcomes red,green
I can do the search and have it tell me it found 3, but it still just puts runs everything through $fruit1 and if I tell it to write $fruit1 to a file it just get a repeating mess
I Need to Get output to a TXT file like so
for #3
FRUIT=orange
Car=Ford
ITEM = string
COLOR ="red,green"
whith each value in a different part of the file/newline
I can't post from the machine the script is on. So values changed to match my example
Function LogWrite
{
Param ([string]$logstring)
Add-content $Logfile -value $logstring
}
LogWrite "Started execution of script.ps1"
$masterlist = Import-Csv ($filepath + "\" + "masterlistfile.csv" )
$FruitName = #()
$NumberName = #()
$Carname = #()
$ItemName = #()
$Colorname = #()
$masterlist |ForEach-Object {
$FruitName += $_.fruit
$NumberName += $_.number
$Carname += $_.car
$Itemname += $_.item
$Colorname += $_.color
}
$number = 3
$FruitIdentified
$CarIdentified
$ItemIdentified
$ColorIdentified
LogWrite "NUmber $number to be searched in masterlistfile "
if ($NumberName -eq $number)
{
LogWrite "Number found in the list..."
$Where = [array]::IndexOf($NumberName, $number)
LogWrite "Fruit Name : $FruitrName[$Where] "
$FruitIdentified = $FruitName[$Where]
$CarIdentified = $CarName[$Where]
$ItemIdentified = $ItemName[$Where]
}
You can use the following to read your CSV and then export the result with your expected output:
$number = 3
Import-Csv path/to/csv.csv | ForEach-Object {
if($_.number -eq $number) {
"for #$number"
foreach($prop in $_.PSObject.Properties.Name -ne 'Number') {
'{0}={2}{1}{2}' -f $prop, $_.$prop, ($null, '"')[$prop -eq 'color']
}
}
} | Set-Content path/to/file.ext
Note that Set-Content will overwrite the export file, if you want to append you would use Add-Content as in your function.
To give some context on what the code does:
Read the CSV and convert it to an object with Import-Csv
Loop over all objects and filter where the value of the Number property is equal to $number.
Output for #$number, in this example would be for #3".
Get all properties of the object using PSObject.Properties.Name and exclude the Number property using -ne 'Number'.
Loop over the Property Names and output '{0}={1}' -f $prop, $_.$prop, here we use the Format Operator -f, {0} would be the Property Name and {1} would be the Property Value. {2} will wrap the value with ".." if the Property Name is color.
The output you would be getting using your CSV for input would be:
for #3
Fruit=orange
Car=Ford
item=string
color="red,green"
I am trying to parse through a .txt dump of firewall rules (100+). I want to search each rule for a specific parameter (ex. set ips-sensor). If that rule contains the parameter, I want the script to print "value found". If not, I want the script to print "value not found". I have treated each rule as a paragraph and used a delimiter on "next". I cannot get the foreach loop to work. Here is what I have:
$paragraphs = Get-Content C:\firewall_rules.txt -Delimiter "next"
#$line = $paragraphs.Split([string[]]"`r`n", [StringSplitOptions]::None)
$exists = $paragraphs | Where-Object { $_ -like '*set ips-sensor*' }
$noexists = $paragraphs | Where-Object {$_ -notlike '*set ips-sensor*'}
$result = foreach ($line in $paragraphs) {$line.Split([string[]]"`r`n", [StringSplitOptions]::None)}
foreach ($result in $paragraphs)
{
if (?)
{
Write-Host "value found"
}
elseif (?)
{
Write-Host "value not found"
}
}
Here is an example of the exact format:
edit 168
set name "Office Stuff"
set srcintf "Office"
set dstintf "port11"
set srcaddr "overthere"
set internet-service enable
set action accept
set schedule "always"
set logtraffic all
set fsso disable
set nat enable
next
edit 174
set name "My Policy"
set srcintf "Office"
set dstintf "port1"
set srcaddr "overthere"
set dstaddr "all"
set action accept
set schedule "always"
set service "ALL"
set utm-status enable
set logtraffic all
set ips-sensor "default"
next
edit 68
set name "Naughty IPs"
set srcintf "Office"
set dstintf "port1"
set srcaddr "all"
set dstaddr "faraway"
set schedule "always"
set service "ALL"
set logtraffic all
set ips-sensor "default"
set fsso disable
my expected output should be -
value not found
value found
value found
Any help is appreciated.
Nice question, I've added comments on the code so you can follow the thought process.
# Define the word we want to match
$find = 'ips-sensor'
# Set Paragraph counter
$z = 1
# $file will be an array with 3 elements / paragraphs given the example we got
foreach($paragraph in $file)
{
# Set the line counter (this will be reset on each paragraph)
$i = 0
# Set a result hashtable and assume we will not find the word we're looking for
$out = [ordered]#{
Paragraph = $z
Status = 'Not Found'
LineNumber = ''
Line = ''
}
# Split this paragraph on new lines and filter only those elements that are
# not empty strings and loop through it
foreach($line in $paragraph -split '\r?\n' -ne '')
{
# Increment the line counter
$i++
# Self explanatory
if($line -match $find)
{
$out.Status = 'Found'
$out.LineNumber = $i
$out.Line = $line.Trim()
# Break the inner loop, if we are here we don't need to keep looping
# over this array
break
}
}
# Cast a pscustomobject which can be easily manipulated and exported
[pscustomobject]$out
# Increment Paragraph counter
$z++
}
Result
Paragraph Status LineNumber Line
--------- ------ ---------- ----
1 Not Found
2 Found 12 set ips-sensor "default"
3 Found 10 set ips-sensor "default"
If you wanted to find multiple words on your dump file, the code would require a few modifications:
$find = 'ips-sensor', 'naughty' -join '|'
$z = 1
foreach($paragraph in $file)
{
$i = 0
$out = [ordered]#{
Paragraph = $z
Status = 'Not Found'
LineNumber = ''
Line = ''
}
foreach($line in $paragraph -split '\r?\n' -ne '')
{
$i++
if($line -match $find)
{
$out.Status = 'Found'
$out.LineNumber = $i
$out.Line = $line.Trim()
[pscustomobject]$out
}
}
if($out.Status -eq 'Not Found')
{
[pscustomobject]$out
}
$z++
}
Result
Paragraph Status LineNumber Line
--------- ------ ---------- ----
1 Not Found
2 Found 12 set ips-sensor "default"
3 Found 2 set name "Naughty IPs"
3 Found 10 set ips-sensor "default"
Since you've already broken the text up into chunks, they can be passed to a foreach-object and you just simply need to test if the desired string is found.
Get-Content C:\firewall_rules.txt -Delimiter 'next' | ForEach-Object {
if($_ -Match 'set ips-sensor'){
"Value found"
}
else{
"Value not found"
}
}
This produces your desired output.
Value not found
Value found
Value found
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'
}
I inherited a script which loops through a set of servers in a server list and then outputs some stuff for each one. It uses StringBuilder to append stuff to a variable and then spits out the results...how do I get the script to store the contents so I can display it at the VERY end with the results of the entire foreach instead of having it print (and then overwrite) on each iteration?
Currently my results look like this:
ServerName1
Text1
Next run:
ServerName2
Text 2
How do I get it to store the data and then output the following at the end so I can email it?
ServerName1
Text1
ServerName2
Text2
My code:
foreach($Machine in $Machines)
{
Invoke-Command -ComputerName $Machine -ScriptBlock{param($XML1,$XML2,$XML3,$URL)
[System.Text.StringBuilder]$SB = New-Object System.Text.StringBuilder
$X = $SB.AppendLine($env:COMPUTERNAME)
if (Test-Path <path>)
{
$PolResponse = <somestuff>
$PolResponse2 = <somestuff>
Write-Host "[1st] $PolResponse" -ForegroundColor Magenta
Write-Host "[2nd] $PolResponse2" -ForegroundColor Magenta
$X = $SB.AppendLine($PolResponse)
$X = $SB.AppendLine($PolResponse2)
}
else
{
$PolResponse = "[1st] No Response"
$PolResponse2 = "[2nd] No Response"
Write-Host $PolResponse -ForegroundColor Red
Write-Host $PolResponse2 -ForegroundColor Red
$X = $SB.AppendLine($PolResponse)
$X = $SB.AppendLine($PolResponse2)
}
} -ArgumentList $XML1, $XML2, $XML3, $URL
}
# Sending result email
<<I want to send the TOTALITY of $SB here>>
You can start by moving the StringBuilder variable declaration outside of the for loop (prior to it)
[System.Text.StringBuilder]$SB = New-Object System.Text.StringBuilder
then FOR LOOP
I don't know if this will be a good solution for what you're asking for or not, but what you could do is create a txt file and every loop in the foreach loop add the information to a txt file. This is one way to store all of the information and then have all of it together at the end.
New-Item -Path "\\Path\to\file.txt" -Itemtype File
Foreach(){
$Stuff = # Do your stuff here
Add-Content -Value $stuff -Path "\\Path\to\file.txt"
}
# Email .txt file ?
# You could use Send-MailMessage to do this possibly
Hopefully this can be helpful for your goal.
I am trying to build a custom script for URL monitoring. I am able to run the URL's from the file and enter the same in a logfile(named with time stamp).
Till here I have completed
Issue is when I compare the values from present(present timestamp) and previous logfile(previous timestamp).
This portion is not working fine. Please help me correct it.
Here is my code trying to compare value line by line from present logfile and previous logfile and run commands to generate output:
# New log is new logfile data
$Newlog = Get-Content $URLlogfile
$old_file = Dir C:\Scripts\logs | Sort CreationTime -Descending | Select Name -last 1
# Old log is Old logfile data
$oldlog = Get-Content $old_file -ErrorAction SilentlyContinue
Foreach($logdata in $Newlog) {
$url = ($logdata.Split(" "))[0]
$nodename = ($logdata.Split(" "))[1]
$statuscheck = ($logdata.Split(" "))[2]
$description = ($logdata.Split(" "))[3]
$statuscode = ($logdata.Split(" "))[4]
Foreach($log1data in $oldlog) {
$url1 = ($log1data.Split(" "))[0]
$nodename1 = ($log1data.Split(" "))[1]
$statuscheck1 = ($log1data.Split(" "))[2]
$description1 = ($log1data.Split(" "))[3]
$statuscode1 = ($log1data.Split(" "))[4]
While ($url = $url1) {
if ($statuscheck = $statuscheck1 ) {
write-output "output is same"
} elseif ($statuscheck = Fail) {
While ($statuscheck1 = Pass) {
write-output "$url is down at $nodename1- testing event sent"
}
} elseif ($statuscheck = Pass) {
While ($statuscheck1 = Fail) {
write-output "$url is up at $nodename1- testing event sent"
}
}
}
Break
}
}
#At end am clearing the old logs except present one
dir C:\Scripts\logs -recurse | where { ((get-date)-$_.creationTime).minutes -gt 3 } | remove-item -force
Per the comment from BenH, the following part of your code needs correcting as follows:
If ($url -eq $url1) {
if ($statuscheck -eq $statuscheck1 ) {
write-output "output is same"
} elseif ($statuscheck -eq 'Fail' -and $statuscheck1 -eq 'Pass') {
write-output "$url is down at $nodename1- testing event sent"
} elseif ($statuscheck -eq 'Pass' -and $statuscheck1 -eq 'Fail') {
write-output "$url is up at $nodename1- testing event sent"
}
}
Corrections:
In your comparison statements the = needs to be -eq. In PowerShell = always assigns a value.
In your comparison statements Pass and Fail need to be surrounded by single quotes so they are treated as strings (otherwise they are treated like function statements, for functions which don't exist).
I've replaced the While statements with If statements. I'm not sure what the intent of those was but I think they'd just get stuck in an infinite loop as the variable they test is never changed from within the loop.