adding data or modifying data in powershell - csv

I have a CSV file with users and dates in it.
I want to run a powershell script that will modify or add to that list.
I have the modify part down, but I can't get the script right to add a line.
Here is what I have.
The file is users.csv with the following data:
Username Date
Johnson 3/10/16
Smith 12/31/15
Brown 3/9/16
When the script runs, I want to check the username. if there is a match, update the date. if there isn't a match add a new line.
Here is my code:
Get time parts
$date=Get-Date -format d
Get username
$user=$env:username
import data and modify
($CSV= import-csv c:\users.csv -delimiter ',') | foreach {
if ($_.username -match $user) {
$_.date=$date
}
}
output
Export-csv c:\users.csv -notypeinformation -force
This will change the date for a user and export the file just fine.
I can't get the code write to read all the usernames and if there isn't a match to add a line at the end with a username and date.
I'm fairly new to powershell.
Thanks for your help
Charles

try this:
$date = Get-Date -format d
$user = $env:username
$csv = ipcsv c:\users.csv
$csv | % {if ($_.username -match $user) {$_.date = $date}}
if ($user -notin $csv.username) {$csv += [pscustomobject]#{Username = $user; Date = $date}}
$csv

Related

Powershell Update Active Directory Users Based on Delimited File

If I have two rows in a CSV file like below (but 200 entries or so).
$Username $Phone
Example.A 911
Example.B 123
How would I get PowerShell to take each row and enter it into a command?
I know how to do it if the phonenumber (Using a for each loop) is the same for everyone, but if everyone has a different phonenumber, how would I go about it then? Can I use a for each loop fetching two rows instead of 1 row from the csv file?
Foreach $Username, $Phonenumber in $CSV
Set-ADuser -identity $Username -PhoneNumber $Phonenumber
Above is how I would like it to be, but that doesn't work.
To do what you're attempting, you just need a couple of slight modifications as follows:
$CSV = Import-Csv -Delimiter "," -Path "\\your\file\path"
foreach ($user in $CSV) {
Set-ADuser -identity $user.Username -PhoneNumber $user.Phonenumber
}

script to output event logs not accessing not working

I am new to powershell, Need to write a script to pull security logs and then place the data in a time stamped csv file in a location but I am getting I get stuck in a loop. My desired outcome is a CSV file in my directory with the security logs and time stamp for file name here is what I got for the part it is flagging.
Get-EventLog "Security" -After $Date `
| Where -FilterScript {$_.EventID -eq 4624 -and $_.ReplacementStrings[4].Length -gt 10 -and $_.ReplacementStrings[5] -notlike "*$"} `
| foreach-Object {
$row = "" | Select UserName, LoginTime
$row.UserName = $_.ReplacementStrings[5]
$row.LoginTime = $_.TimeGenerated
$eventList += $row
$variable | Export-Csv c:\output.csv
}
$eventList
Export-Csv : Cannot bind argument to parameter 'InputObject' because it is null.
At line:12 char:21
I am guessing the issue is here? Again my apologize very little scripting background, just trying to make a process better.
$variable | Export-Csv c:\output.csv
Yes, you don't define $variable within your script, that is why you getting this exception. It looks like you trying to export a bunch of EventLog entries as csv, so the Export-Csv cmdlet probably should belong outside the Foreach-Objectcmdlet. Maybe you want to do something like this:
Get-EventLog "Security" -After $Date `
| Where -FilterScript {$_.EventID -eq 4624 -and $_.ReplacementStrings[4].Length -gt 10 -and $_.ReplacementStrings[5] -notlike "*$"} `
| foreach-Object {
$row = "" | Select UserName, LoginTime
$row.UserName = $_.ReplacementStrings[5]
$row.LoginTime = $_.TimeGenerated
$row # this will put the current row to the pipeline
} | Export-Csv 'c:\output.csv'

PowerShell Error: Import-CSV Cannot Open File

My PowerShell code is tripping some strange error codes, which I have thoroughly searched for to no avail.
I am trying to create a script that calculates some basic statistics for a number of CSV files, which seems to work until I try to create and populate new columns.
The error code I'm getting is:
Import-Csv: Cannot open file "C:\zMFM\Microsoft.Powershell.Commands.GenericMeasureInfo".
At C:\zMFM\StatsDebug.ps1:46 Char:21
+$STATS2 = Import-CSV <<< $STATS
+CategoryInfo : OpenError (:) [Import-Csv], FileNotFoundException
+FullyQualifiedErrorId : FileOpenFailure.Microsoft.Powershell.Commands.ImportCsvCommand at C:\zMFM\statsdebug.ps1:55 char:20
That's followed by an error using a null expression, but I assume fixing this problem with Import-Csv will in turn fix that error. Here's my code, any help would be great, thanks!
$i = 1
#$colSTDDEV = New-Object System.Data.DataColumn StdDev,([double])
$colVZA = New-Object System.Data.DataColumn VZA,([double])
#$colVAZ = New-Object System.Data.DataColumn VAZ,([double])
While ($i -le 211) {
#Set the variable to the filename with the iteration number
$filename = "c:\zMFM\z550Output\20dSummer\fixed20dSum550Output$i.csv"
#Check to see if that a file with $filename exists. If not, skip to the next iteration of $i. If so, run the code to collect the
statistics for each variable and output them each to a different file
If (Test-Path $filename) {
#Calculate the Standard Deviation
#First get the average of the values in the column
$STDEVInputFile = Import-CSV $filename
#Find the average and count for column 'td'
$STDEVAVG = $STDEVInputFile | Measure-Object td -Average | Select Count, Average
$DevMath = 0
# Sum the squares of the differences between the mean and each value in the array
Foreach ($Y in $STDEVInputFile) {
$DevMath += [math]::pow(($Y.Average - $STDEVAVG.Average), 2)
#Divide by the number of samples minus one
$STDEV = [Math]::sqrt($DevMath / ($STDEVAVG.Count-1))
}
#Calculate the basic statistics for column 'td' with the MEASURE-OBJECT cmdlet
$STATS = Import-CSV $Filename |
Measure-Object td -ave -max -min
#Append the standard deviation variable to the statistics array and add the value
$STATS2 = Import-CSV $Stats
$VZA = $filename.VZA
#$VAZ = $filename.VAZ #COMMENTED FOR DEBUGING
#$STATS2.Columns.Add($colSTDDEV) #COMMENTED FOR DEBUGING
#$STATS2[0].StdDev = $STDEV #COMMENTED FOR DEBUGING
$STATS2.Columns.Add($colVZA)
$STATS2[0].VZA = $VZA
#$STATS2.Columns.Add($colVAZ) #COMMENTED FOR DEBUGING
#$STATS2[0].VZA = $VAZ #COMMENTED FOR DEBUGGING
#Export the $STATS file containing everything you need in the correct folder
Export-CSV -notype "c:\zMFM\z550Output\20dSummer\20dSum550Statistics.csv"
}
$i++
}
$STDEVInputFile = Import-CSV $filename
...
$STATS = Import-CSV $Filename |
Measure-Object td -ave -max -min
# $STATS here will be type [GenericMeasureInfo], so you cannot use this as a filename.
$STATS2 = Import-CSV $Stats
# Are you trying to import $filename a third time here? You can't use $Stats because it's a [GenericMeasureInfo] object, not a [string].
Based on your code, it looks like you're trying to import a CSV with a filename of type [Microsoft.PowerShell.Commands.GenericMeasureInfo]. Filenames are strings. Also, why are you importing $filename twice? Would recommend importing it once, then operating off of the variable you saved it to.
Would also recommend changing your while loop to 1..211 | ForEach-Object. That way you won't have to worry about whether $i is less than or equal to your static number. Not a huge deal, but would make the code a little more readable.
TL;DR
Import-CSV $Stats is the problem. $Stats is not a valid filename, so you can't open/import it.

Powershell: Reading in a column from a .CSV file and then adding a specific string to the beginning and exporting again

I'm attempting to write a script which will read in a CSV generated by querying AD for user information (that part is done) but then will allow me to add a string to the beginning of each value of a column in the CSV file and then export it.
For instance we have this CSV file:
"displayname","Office"
Bob,7142
Janet,8923
SantaClaus,0912
NicCage,0823
I want to take each entry for "Office", add the string "BUG" before it and then export it back out. The modified CSV should look like:
"displayname","Office"
Bob,BUG7142
Janet,BUG8923
SantaClaus,BUG0912
NicCage,BUG0823
At this point, I've been attempting to read in just the "Office" column and then displaying it with "Write-Host". The idea being that if I can do that then maybe I can create a new variable that would be something like:
$BUG = "BUG"
$NewVar = $BUG$Office
Which would hopefully look like the second CSV file. I am extremely new to powershell scripting.
The attempts I've made so far are these:
Attempt #1:
$UserList = Import-CSV C:\Users\username\CSV.csv
$UserList | ForEach-Object ($_.Office) { $UserList }
Attempt #2:
$projectName = import-csv C:\Users\username\CSV.csv | % {$_.Office}
$BUG = "BUG"
$projectName | ForEach-Object ($_) {$projectName}
Attempt #3:
$UserList = Import-CSV C:\Users\username\CSV.csv
#ForEach ($Office in $Userlist) {
#Write-Host $UserList.Office
#}
Attempt #4:
Import-Csv "C:\Users\username\CSV.csv" -Header ("displayname","Office","whenCreated","EmailAddress") | Select-Object Office | Export-CSV -Path C:\users\Username\test.csv
I have gotten it to read out just the Office numbers before using the ForEach-Object loop structure but then it never stops reading out the office numbers so that's unhelpful.
I think I'm going in the right direction, but I just can't figure out how to modify a column like this.
Instead of trying to extract the Office column, just pipe the full data set (all columns) to ForEach-Object, change the value of the Office property and pipe it back to Export-Csv:
$Prefix = "BUG"
Import-Csv .\file.csv | ForEach-Object {
$_.Office = $Prefix + $_.Office
$_
} | Export-Csv .\file_modified.csv -NoTypeInformation

Export Matches array object to CSV in Powershell

I have a powershell script to find particular instances and then export them to CSV. Here's an example of the way the code works
$items = "Hello Tim", "Hola Bob", "Hello Susan"
$filter = $items | Select-String -Pattern "Hello"
$filter | Select-Object Line, Matches | Export-Csv "C:\log.csv"
Invoke-Item "C:\log.csv"
When I run the Select-Object in PS, it's nicely formatted info like this:
However, when I export to CSV, it exports the whole object and writes it as the following string: System.Text.RegularExpressions.Match[]
How can I get it to export just the first match or a listing of all matches into a single field when writing to CSV?
Here is one way using a PSObject:
$items = "Hello Tim", "Hola Bob", "Hello Susan"
$filter = $items | Select-String -Pattern "Hello"
$filter | % {New-Object PSObject -property #{
Line = $_.Line
Matches = $_.Matches.Groups[0].Value}
} | Export-Csv "C:\log.csv" -NoTypeInformation
Quickly note that Matches is an array which may create issues exporting to a csv.
Try joining the array into a string with a chosen delimiter. I used "::" in my example.
$filter | Select Line, #{Expression={$_.Matches -join "::"}; Label="Matches"} | Export-Csv "C:\log.csv"