Powershell Logging_Functions Causing Unexplained Error - powershell

I managed to get rid of the message by changing line 53 to :
New-Item -Path $sFullPath -ItemType File -Force
Which also allows removal of the Test-Path above this (thanks to -Force), But I don't understand why New-Item would try to create a new folder when -ItemType File has been specified, AND the path and name have both been provided ...
I am trying to use Logging_Functions.ps1 Module which I got here.
This is how I am calling it:
."\\DC1\NETLOGON\PSSubs\Logging_Functions.ps1"
Log-Start -LogPath "\\DC1\NETLOGON\PSSubs" -LogName "Test_Log.log" -ScriptVersion "1.5"
As per the documentation. However, when running the above I am seeing this annoying message:
New-Item : The file '\DC1\NETLOGON\PSSubs' already exists.
At \DC1\NETLOGON\PSSubs\Logging_Functions.ps1:53 char:5
+ New-Item -Path $LogPath -Value $LogName -ItemType File
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : WriteError: (\DC1\NETLOGON\PSSubs:String) [New-Item], IOException
+ FullyQualifiedErrorId : NewItemIOError,Microsoft.PowerShell.Commands.NewItemCommand
Even though this error appears, the file is created and I have no idea why it is complaining about the folder name, as line 53 is not asking it to create the folder.
When I run the exact same line inside the actual Logging_Functions.ps1 file, it works without error. I've included the Log-Start function below (which I altered slightly on line 53 to replace -Value with -Name as this seems correct):
Function Log-Start{
[CmdletBinding()]
Param (
[Parameter(Mandatory=$true)][string]$LogPath,
[Parameter(Mandatory=$true)][string]$LogName,
[Parameter(Mandatory=$true)][string]$ScriptVersion
)
Process{
$sFullPath = $LogPath + "\" + $LogName
#Check if file exists and delete if it does
If((Test-Path -Path $sFullPath)){
Remove-Item -Path $sFullPath -Force
}
#Create file and start logging
New-Item -Path $LogPath -Name $LogName -ItemType File
Add-Content -Path $sFullPath -Value "***************************************************************************************************"
Add-Content -Path $sFullPath -Value "Started processing at [$([DateTime]::Now)]."
Add-Content -Path $sFullPath -Value "***************************************************************************************************"
Add-Content -Path $sFullPath -Value ""
Add-Content -Path $sFullPath -Value "Running script version [$ScriptVersion]."
Add-Content -Path $sFullPath -Value ""
Add-Content -Path $sFullPath -Value "***************************************************************************************************"
Add-Content -Path $sFullPath -Value ""
#Write to screen for debug mode
Write-Debug "***************************************************************************************************"
Write-Debug "Started processing at [$([DateTime]::Now)]."
Write-Debug "***************************************************************************************************"
Write-Debug ""
Write-Debug "Running script version [$ScriptVersion]."
Write-Debug ""
Write-Debug "***************************************************************************************************"
Write-Debug ""
}
}
Can anyone please help explain what the difference is here? Why would one way cause an error and not the other, when they are supposedly doing the exact same thing? Thanks!

You can change all of this:
#Check if file exists and delete if it does
If((Test-Path -Path $sFullPath)){
Remove-Item -Path $sFullPath -Force
}
#Create file and start logging
New-Item -Path $LogPath -Name $LogName -ItemType File
To the following one liner, as the -Force will overwrite any file that already exists:
New-Item -Path $sFullPath -ItemType File -Force

Related

Powershell move multiple files to multiple directories

I have problems with my script. My goals is move files from multiple directories to multiple targets using LastWriteTime. When I run my script I get error code:
Move-Item : Cannot find path 'W:\files\cv\data\test.csv' because it does not exist.
At line:28 char:13
+ Move-Item -Path "$($checkThis.Source)$($file.Name)" -Dest ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (W:\files\cv\data\test.csv:String) [Move-Item], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.MoveItemCommand
Script:
function Write-Log($str) {
Add-Content -Path $logFilePath -Value "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") $str"
}
$logpath = "C:\temp\Logs\"
$logFilePath = $logpath + "\test_files" + $(Get-Date -Format "yyyyMMdd") + ".log"
$checkThese = #(
[pscustomobject]#{Id='first'; Source='W:\files\cv\data'; Target="D:\files\archive\cv\Data\"}
[pscustomobject]#{Id='second'; Source='W:\files\tv\data'; Target="D:\files\archive\tv\Data\"}
)
#Move files from source dir to archive after this many days since last write
$archiveAfterDays = 1*1
Write-Log "[BEGIN]"
ForEach($checkThis in $checkThese) {
Write-Log "[INFO] Process $($checkThis.Id) archive"
Write-Log "[INFO] Start archive"
Write-Log "[INFO] Check folder $($checkThis.Source) for files to archive"
}
#Archive files older than $archiveAfterDays
$files = Get-ChildItem $checkThis.Source | Where-Object {$_.LastWriteTime -lt (Get-Date).AddDays(-$archiveAfterDays)}
ForEach ($file in $files)
{
Move-Item -Path "$($checkThis.Source)$($file.Name)" -Destination "$($checkThis.Target)$subfolder$($file.Name)" -Force
}
Write-Log "[END]"
Problem solved:
ForEach($checkThis in $checkThese) {
Write-Log "[INFO] Process $($checkThis.Id) Copy files to monthly DB"
Write-Log "[INFO] Start copy"
Write-Log "[INFO] Check folder $($checkThis.Source) for files to move"
$files = Get-ChildItem $checkThis.Source | Where-Object {$_.LastWriteTime -gt (Get-Date).AddDays(-1)}
ForEach ($file in $files) {
Copy-Item -Path "$($checkThis.Source)\$($file.Name)" -Destination "$($checkThis.Target)\$($file.Name)" -Force
}
}

Copy Files on Same Directory using Powershell

I am trying to write powershell Script which will create backupfolder on same Path where Application exist and need to copy the folders & files into backupfolder before deploying. Below are the command was using to perform but am getting error
$Source = "C:\XYZ"
$BackupFolder = New-Item -ItemType Directory -Force -Path $source_$(Get-Date)
Copy-Item -Path $Source\* $BackupFolder -Force
Error: Cannot copy item C:\XYZ\Backup_18-02-2017 on to itself
Try:
Copy-Item $Source\* $BackupFolder -Exclude $BackupFolder
That will eliminate the folder that you are copying into as a source that is being copied from.
Variables can contain underscores. The following works and displays the string "asdf"
$a_ = "adsf"; $a_
Your New-Item cmdlet call should have failed since $source_ is not a variable and would return null. This is default behavior for PowerShell. When I run your code as is I get the following:
New-Item : Cannot find drive. A drive with the name '02/18/2017 22' does not exist.At line:1 char:1
+ New-Item -ItemType Directory -Force -Path "$source_$(Get-Date)" -what ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (02/18/2017 22:String) [New-Item], DriveNotFoundException
+ FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.NewItemCommand
So I would have expected your folder variable to be null. wOxxOm brings this up in comment as well
Several options to address what I am sure is the partial source of your issue.
$BackupFolder = New-Item -ItemType Directory -Force -Path "$source`_$(Get-Date)"
$BackupFolder = New-Item -ItemType Directory -Force -Path "$($source)_$(Get-Date)"
$BackupFolder = New-Item -ItemType Directory -Force -Path ("{0}_{1} -f "$source, Get-Date)
You will still have to try and exclude this folder from the copy as well like Keith Hill's answer is telling you
Copy-Item $Source\* $BackupFolder -Exclude $BackupFolder
try Something like this
$Source = "C:\XYZ"
$Destination="{0}{1:yyyyMMdd}" -f $source, (Get-Date)
New-Item -ItemType Directory -Force -Path $Destination
Copy-Item -Path $Source\* $Destination -Recurse -Force
If I understand the question correctly. You want to take "C:\XYZ" and backup into the same directory called "C:\XYZ\backup_$DATE". What you will actually do is create a loop that will break once it reaches the max 248 characters. If we use the -exclude option then we can exclude the backup directory "C:\XYZ\backup_$DATE".
This function will do the trick and also gives you error handling.
Function Get-CopyDirectory{
#####################
# Dynamic Variables #
#####################
$Date = Get-Date -format ddMM-yyyy
$Exclude="Backup*"
####################
# Static Variables #
####################
$AppPath = "F:\Test\"
$BackupPath = "$AppPath\BACKUP_$Date\"
if (Test-Path $BackupPath) {
Write-Host "Backup Exist" -f Cyan
}
else
{
Copy-Item "$AppPath\*" $BackupPath -Exclude $Exclude -recurse -verbose
}
}
CLS
Get-CopyDirectory

else not being executed within foreach

I am trying to write the following script, which checks a folder for a set of files, if they exist, move them to an "archive" folder. If they don't, write an error message to screen and to a log file.
The files move fine, so the first part of the IF is working correctly, but if there are no files to move, the else should kick in and output the error....but it is not.
variables.ps1:
#----- define parameters -----#
#----- Treat All Errors as Terminating -----#
$ErrorActionPreference = "Stop"
#----- Set count to 0 -----#
$count = 0
#----- get current date ----#
$Now = Get-Date
#----- define amount of days ----#
$Days = "0"
#----- define folder where files are located ----#
$SourceFolder = "C:\HG1\Test\Files"
#----- define folder where files are to be moved to ----#
$DestFolder = "C:\HG1\Test\Files\Archive"
#----- define folder where files are to be moved to ----#
$LogPath = "C:\HG1\archive.log"
#----- define extension ----#
$Extension = "*.log"
#----- define LastWriteTime parameter based on $Days ---#
$LastWrite = $Now.AddDays(-$Days)
#----- get files based on lastwrite filter and specified folder ---#
$Files = Get-Childitem $SourceFolder -Include $Extension -Recurse | Where {$_.LastWriteTime -le "$LastWrite"}
archive_files.ps1
#----- Call variables file variables.ps1 - MUST BE IN SAME LOCATION AS SCRIPT ----#
. ./variables.ps1
foreach ($File in $Files)
{
if ($File -ne $NULL)
{
move-item -path $File.FullName -destination $DestFolder
Add-Content $LogPath -value ("$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')) `t INFO: Archived File $File")
}
else
{
write-host "ERROR: No files to archive" -ForegroundColor "Red"
Add-Content $LogPath -value ("$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')) `t ERROR: No files to archive")
}
}
Add-Content $LogPath -value ("$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')) `t INFO: ***Archiving script completed successfully***")
Any help would be greatly appreciated.
#----- Call variables file variables.ps1 - MUST BE IN SAME LOCATION AS SCRIPT ----#
. ./variables.ps1
if ($File)
{
foreach ($File in $Files)
{
move-item -path $File.FullName -destination $DestFolder
Add-Content $LogPath -value ("$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')) `t INFO: Archived File $File")
}
}
else
{
write-host "ERROR: No files to archive" -ForegroundColor "Red"
Add-Content $LogPath -value ("$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')) `t ERROR: No files to archive")
}
Add-Content $LogPath -value ("$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')) `t INFO: ***Archive script completed successfully***")
here,
Foreach each won't process for $null value
so include foreach if value is not null
if won't enter for $null value so " -ne $null is" not necessary
hopes this works for you,
Regards,
Kvprasoon
You should use the Test-Path cmdlet to check whether the file exist:
foreach ($File in $Files)
{
if (Test-Path $File)
{
move-item -path $File.FullName -destination $DestFolder
Add-Content $LogPath -value ("$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')) `t INFO: Archived File $File")
}
else
{
write-host "ERROR: No files to archive" -ForegroundColor "Red"
Add-Content $LogPath -value ("$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')) `t ERROR: No files to archive")
}
}
Add-Content $LogPath -value ("$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')) `t INFO: ***Archiving script completed successfully***")
You've got that logic backwards there.
Each $File in $Files will always be something, but the $Files collection itself may be empty:
if(-not $Files)
{
foreach($File in $Files)
{
Move-Item -Path $File.FullName -Destination $DestFolder
Add-Content $LogPath -Value ("$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')) `t INFO: Archived File $File")
}
}
else
{
Write-Host "ERROR: No files to archive" -ForegroundColor "Red"
Add-Content $LogPath -Value ("$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')) `t ERROR: No files to archive")
}
Add-Content $LogPath -value ("$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')) `t INFO: ***Archiving script completed successfully***")

Powershell Output to my log location not working

I am looking to log the output of my script to a log file. But not able to get the output to a file.
Set-ExecutionPolicy RemoteSigned
$server_names = Get-Content "E:\Bibin\Copy\complist.txt"
$Folder=$((Get-Date).ToString('yyyy-MM-dd'))
$Logfile = "E:\Bibin\Copy\copy.log"
Function LogWrite
{
Param ([string]$logstring)
Add-content $Logfile -value $logstring
}
Foreach ($server in $server_names)
{
$FileExists = Test-Path "\\$server\C$\temp\TEST\*"
If ($FileExists -eq $True)
{
New-Item "\\$server\C$\temp\TEST\$Folder" -type directory
Move-Item "\\$server\C$\temp\TEST\*" -Destination "\\$server\C$\temp\TEST\$Folder" -force
Copy-Item "\\DC1NAS02P00\data\IT\CPS\Projects\NGNet\CpsServerUpgradeFiles\Upgrade Version 2.0\2003_Files\*.*" -Destination "\\$server\C$\temp\TEST" -Recurse
}
Else
{
New-Item "\\$server\C$\temp\TEST" -type directory
Copy-Item "\\DC1NAS02P00\PDSdata\IT\CPS\Projects\NGNet\CpsServerUpgradeFiles\Upgrade Version 2.0\2003_Files\*.*" -Destination "\\$server\C$\temp\TEST" -Recurse
}
}
Also I want some time gap between New_item and Move-item, since it is saying file is already in use ..
Thanks
Bibin
instead of using Add-Content use Out-File.
Also try robocopy instead of copy, this will wait for the locks to release before copying.

Exception Logging in PowerShell

I am currently having an issue logging exceptions in my PowerShell script. I am trying to copy a file to C:\Windows\System32 and I want to add an error line to my log file if it errors. I have tried this two ways so far.
Example 1:
$LogPath = "C:\Test.txt
$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
Copy-Item $scriptPath\Devcon.exe C:\Windows\System32 -ErrorAction SilentlyContinue -ErrorVariable $Errors
Foreach($error in $Errors)
{
add-content -Path $LogPath -Value $($error.Exception) -Force
}
Example 2:
$LogPath = "C:\Test.txt
$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
Try{
Copy-Item $scriptPath\Devcon.exe C:\Windows\System32
}
Catch [System.Exception]
{
add-content -Path $LogPath -Value "There was an error why trying to copy the file." -Force
add-content -Path $LogPath -Value $Error -Force
}
I can add items to the log file so I know it's not a permissions issue with the file. What am I missing?
I believe the error you are getting is non-terminating. This is why it does not end up in a catch block.
Try this instead of your Copy-Item line:
Copy-Item $scriptPath\Devcon.exe C:\Windows\System32 -ErrorAction Stop
Help on ErrorAction (MSDN).