Overwrite an existing file with date as filename - powershell

I am very new to PowerShell scripting. I am trying to overwrite an existing file with date and time in it's file name.
Here is what i'm using.
$LogName = "Security"
$EventID = 4725
$Date = ((get-date).addDays(-1))
$CurrentDate = Get-Date
$CurrentDate = $CurrentDate.ToString('MM-dd-yyyy_hh.mm.ss')
get-eventlog $LogName $EventID -after $Date | Export-CSV $Path -notypeinformation | Out-File -Filepath $Path -Append
However, upon running, it returns with an error that says
Out-File : The process cannot access the file because it is being used by another process
I hope you guys can help me with this. Thanks!

Try using ConvertTo-Csv not Export-CSV.
Get-EventLog $LogName $EventID -after $Date | ConvertTo-Csv -NoTypeInformation | Out-File -Filepath $Path -Append
The error is down to the fact that your trying to read and write to a file ($path) at the same time.
This will stop Export-CSV creating a file before you append to the same file, cutting out the error.

Related

I want to use get-counter ”\\$env:COMPUTERNAME\memory\% committed bytes in use” to append to a csv in the next line

How can i append the get-counter into the cell in my csv without overwriting the current data.
$path = "v:\logg\logg.csv"
$ram = Get-Counter "\\$env:COMPUTERNAME\minne\% använda dedikerade byte"
$drivers = Get-Volume |Where-Object {$_.DriveLetter-ne $null}| select DriveLetter,Size,SizeRemaining,#{e={$_.Size - $_.SizeRemaining};l="Used"},#{e={[math]::Round(100 / ($_.size / $_.SizeRemaining) )};l="Total %"}
$drivers | Export-Csv $path -NoTypeInformation -Append -Force
Get-Date -Format "yyyy-MM-dd HH:mm"|Out-File $path -Append
I want it to look like this but with the get-counter added to the next empty cell:
If I try to add the $ram with add-content or out-file it will overwrite the whole file and remove the $drivers
If i try to do it like this:
$path = "v:\logg\hej.csv"
$ram = Get-Counter "\\$env:COMPUTERNAME\minne\% använda dedikerade byte"
$ram |Export-Csv $path -NoTypeInformation -Append -Force
$drivers = Get-Volume |Where-Object {$_.DriveLetter-ne $null}| select DriveLetter,Size,SizeRemaining,#{e={$_.Size - $_.SizeRemaining};l="Used"},#{e={[math]::Round(100 / ($_.size / $_.SizeRemaining) )};l="Total %"}
$drivers | Export-Csv $path -NoTypeInformation -Append -Force
It will look like this, overwriting the whole part of $drivers
for just the committed bytes %, you can use this ...
$Counter = '\\{0}{1}' -f $env:COMPUTERNAME, '\Memory\% Committed Bytes in Use'
$RAM_CommBytesInUse_Pct = [int](get-counter -Counter $Counter).
CounterSamples[0].
CookedValue
output on my system just now = 39
however, you are not making a CSV file when you add all these things that don't have the same columns. for instance, the date you inserted is a string in the DriveLetter column. to make a real CSV file, you will need to rearrange your properties in a new object.

powershell append date time to beginning of file

I'm working to get a powershell command that will dump the value into output.xml. First a value is requested from the user, then the application log is parsed for that value and the results are returned to output.xml. I would like to also tag the beginning with the date time stamp, but haven't been able to figure it out. This is what I have come up with to accomplish the parsing, and I have attempted to use a few other methods:
read-host (Get-Date).tostring("dd-MM-yyyy-hh-mm-ss")
I guess I don't understand exactly where to put this part of the code to make it work. My whole script looks like this.
$value = read-host "Enter your search value"
Get-WinEvent -Logname application -EA silentlycontinue | ?{$_.LevelDisplayName -eq "Error" -or $_.LevelDisplayName -eq "Warning"} | Out-File '$output.xml' -Append
Use Out-File to write the first line(s) of the file as well:
$value = Read-Host "Enter your search value"
"# $(Get-Date -Format 'dd-MM-yyyy-hh-mm-ss')" |Out-File output.log
"# User $($env:USERNAME) supplied the following search term '$value'" |Out-File output.log -Append
Get-WinEvent -Logname application -EA silentlycontinue | ?{$_.LevelDisplayName -eq "Error" -or $_.LevelDisplayName -eq "Warning"} | Out-File output.log -Append
If all you're looking for is the first line to be the data use this instead.
(Get-Date).tostring("dd-MM-yyyy-hh-mm-ss") | Out-File .\output.xml
Don't forget to use -Append if you're adding more lines after the date.
A simple edit to your write method:
Out-File "$(Get-Date -UFormat '%Y-%m-%d-%H-%M-%S-')$output.xml" -Append

Unable to start scriptblock as background or remote job, works fine executing directly

I have a scriptblock I would like to run as a background job. Below is the command I would like to run:
Get-ChildItem -Recurse $source | Get-DfsrFileHash | Export-csv -Append C:\Temp\Test_Source_Checksum.csv
If I run this command it goes through successfully with no issues.
I have tried the following for 'Start-Job'
Start-Job -ScriptBlock { Get-ChildItem -Recurse $source | Get-DfsrFileHash | Export-csv -Append C:\Temp\Test_Source_Checksum.csv }
This results in 'Get-Job' displaying as completed, when it actually hasnt, or doesnt appear to have judging by the missing file: 'Test_Source_Checksum.csv'
I have also tried using the following for 'Invoke-Command'
Invoke-Command -AsJob -ComputerName ($env:COMPUTERNAME) -ScriptBlock { Get-ChildItem -Recurse $source | Get-DfsrFileHash | Export-csv -Append C:\Temp\Test_Source_Checksum.csv }
This results in 'Get-Job' displaying failed.
If I display the failure using:
(get-job -name Job38).JobStateInfo.Reason
I get nothing back...
Am I using Start-Job/Invoke-Command incorrectly here?
The reason I would like to run this as a background job is, im trying to copy large amounts of data and checksum it (for a DFS Migration). I would like to copy the data in smaller subsets, then checksum the data which has been copied whilst its copying the next batch over...rinse and repeat
Thanks,
Chris
EDIT:
Here is a copy of the whole script:
##----------------------------------------------------------------------------------##
$source="E:\DFSR_Migration_Test_Prod"
$dest="F:\DFSR_Migration_Test_Prod"
$what = #("/COPYALL","/B","/SEC","/E","/xd","dfsrprivate")
$options = #("/R:6","/tee","/MT:32")
$cmdArgs = #("$source","$dest",$what,$options)
##----------------------------------------------------------------------------------##
robocopy #cmdArgs
Write-Output "Prod_Copied #" (get-date) | Out-File C:\Temp\File_Copy.txt -Encoding ascii -Append -NoClobber
Write-Output "Initiating Prod Source Checksum #" (get-date) | Out-File C:\Temp\File_Copy.txt -Encoding ascii -Append -NoClobber
Start-Job -ScriptBlock { Get-ChildItem -Recurse $source | Get-DfsrFileHash | Export-csv C:\Temp\Prod_Source_Checksum.csv }
Write-Output "Initiating Prod Destination Checksum #" (get-date) | Out-File C:\Temp\File_Copy.txt -Encoding ascii -Append -NoClobber
Start-Job -ScriptBlock { Get-ChildItem -Recurse $dest | Get-DfsrFileHash | Export-csv C:\Temp\Prod_Destination_Checksum.csv }
How are you passing $source? Because if you're doing nothing other than writing the variable name it'll be null, and if it's null you'll be executing Get-ChildItem for $pwd.Path on the remote system.
The simplest solution is to make $source into $using:Source.
Invoke-Command -AsJob -ComputerName ($env:COMPUTERNAME) -ScriptBlock { Get-ChildItem -Recurse $using:source | Get-DfsrFileHash | Export-csv -Append C:\Temp\Test_Source_Checksum.csv }
In addition to the good information above, remember that starting a job is a lot like opening a new console (that you cannot see directly), this means that you may need to re-connect or re-authenticate. As an example, if you want to start a new job that uses PowerCLI, you will have to re-connect to your vCenter Server so in your scriptblock, you would preface your command with (connect-viserver...): start-job -scriptblock {connect-viserver -server <vCenterServer>; powercli command}.

Weird new line behavior between Windows 7 Notepad and Windows 2012 Server Notepad

I've whipped up a script that deletes old video directories, and it will create a log of what has been deleted in a .txt file.
Running the script on my Windows 7 PC, the .txt file in Notepad puts each output on a new line.
Running the script on my Windows 2012 Server, the .txt file in Notepad puts the output on the same line. If I open the log file with Wordpad, the outputs are on new lines.
Here's what the powershell script looks like:
$limit = (Get-Date).AddDays(0)
$logFile = "C:\BodyCam\bodycamlog.txt"
$output = "The following directories contain incorrect video dates" + "`n"
#Throw a timestamp on the log file
Add-Content -Path $logFile "=======$(Get-Date)======="
#Get all of the paths for each camera
$paths = Get-ChildItem -Path "D:\Videos\" |Select-Object -ExpandProperty FullName
#for each path we found
foreach ($pa in $paths) {
# Delete directories older than the $limit.
$dir = Get-ChildItem -Path $pa -Recurse -Force | Where-Object { $_.PSIsContainer -and $_.CreationTime -lt $limit }
$dir | Remove-Item -Recurse -Force
$dir | Select -Expand FullName | Out-File $logFile -append
if ($dir -match "1970"){
$output += $pa + "`n"
}
}
Send-MailMessage -to "Ray <***>" -from "BodyCamScript <***>" -subject "Bad Bodycam Date Found" -body $output -SmtpServer ***
What's the deal here?
The default encoding for Add-Content is ASCII, but the default for Out-File is Unicode. Use the encoding parameter on both to force the same encoding and it should work as you expect.

Powershell extracting logs based upon interval?

I have script logic as follows:-
check if the folder is empty
If yes Use the same command with exception time period of last 30 days. i.e StartDate etc
If folder not empty get / extract the logs for 1 day using same command
just tweaking timesettings.
the script will be scheduled to run every 5 minutes. For every run extract using the same command for 1 day saves the result in temp.csv and compare it most updated copy of final-admin.csv.
If changes found; write difference / over-write in
final-admin.csv
code
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010
$outcsv='c:\Mail-audit-results\Final-mail-admin.csv'
if(Get-ChildItem C:\Mail-audit-results){
$enddate=[datetime]::Today
$Startdate=$enddate.AddDays(-1)
$splat=#{
Identity='mail.test-nw.com'
LogonTypes=#('Admin','Delegate')
ShowDetails=$true
StartDate=$Startdate
EndDate=$enddate
}
Search-MailboxAuditLog #splat | Export-Csv c:\Mail-audit-results\temp_results.csv -NoTypeInformation -Append
$Old = Import-CSV $outcsv
$New = Import-CSV c:\Mail-audit-results\temp_results.csv
$New | ?{$Old -notmatch $_} | Export-CSV $outcsv -notype
}
#process items when files found
}else{
# process when no files found.
$enddate=[datetime]::Today
$Startdate=$enddate.AddDays(-30)
$splat=#{
Identity='mail.test-nw.com'
LogonTypes=#('Admin','Delegate')
ShowDetails=$true
StartDate=$Startdate
EndDate=$enddate
}
Search-MailboxAuditLog #splat | Export-Csv $outcsv -NoTypeInformation -Append
}
Get-ChildItem 'c:\Mail-audit-results\Final-mail-admin.csv' | ForEach {
Else
{
return 0;
}
}
Problem-points
How can I change the format of date in mm/dd/yyy format in section
$enddate=[datetime]::Today
$Startdate=$enddate.AddDays(-1)
How to overwrite with difference data?
$New | ?{$Old -notmatch $_} | Export-CSV $outcsv -notype
I don't want to write to third file the difference I want original file $outcsv to get written; would the above command overwrite/ or just append?
Thanks.
You can change your dates using -Uformat switch
$enddate= Get-Date ([datetime]::Today) -UFormat "%m%d%Y"
$Startdate= Get-Date ($enddate.AddDays(-1)) -UFormat "%m%d%Y"
The line
$New | ?{$Old -notmatch $_} | Export-CSV $outcsv -notype
will overwrite data, Export-CSV -Append will append.