Close a file handle opened by .NET - powershell

I'm working on a script to rename files based on EXIF data.
param([string]$path)
# http://blogs.technet.com/b/jamesone/archive/2007/07/13/exploring-photographic-exif-data-using-powershell-of-course.aspx
[reflection.assembly]::loadfile( "C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Drawing.dll") | out-null
function MakeString {
$s=""
for ($i=0 ; $i -le $args[0].value.length; $i ++) {
$s = $s + [char]$args[0].value[$i]
}
return $s
}
$files = Get-ChildItem -Path $path
foreach ($file in $files) {
if ($file.Extension -ne ".jpg") { continue }
if ($file.Name -match "^(\d+)-(\d+)-(\d+)") { continue }
$exif = New-Object -TypeName system.drawing.bitmap -ArgumentList $file.FullName
$captureDate = MakeString $exif.GetPropertyItem(36867)
$captureDate = ($captureDate -replace ":", '-').Substring(0,19)
$newFilename = $captureDate + " " + $file.Name.Trim()
$file.Name + " -> " + $newFilename
$file |Rename-Item -NewName $newFilename
}
Reading the date from EXIF is no problem, but when I try to rename the file I get this error message:
Rename-Item : The process cannot access the file because it is being used by another process.
At D:\Norwegen\RenamePhotos.ps1:25 char:12
+ $file |Rename-Item -NewName $newFilename
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : WriteError: (D:\Norwegen\P1270465 (1920x1433).jpg:String) [Rename-Item], IOException
+ FullyQualifiedErrorId : RenameItemIOError,Microsoft.PowerShell.Commands.RenameItemCommand
When I monitor the directory in ProcMon I can see that the files are closed rather late:
(look at the highlighted line, it's from an earlier file in the middle of the entries from the file currently being processed)
So, how can I close the file (which is probably still open from the EXIF read) so I can rename it?
What I already tried to close the open file:
Remove-Variable exif
$file.Close()

Since you only read from the the file, then a call to Dispose() should do the trick. Ex.
foreach ($file in $files) {
if ($file.Extension -ne ".jpg") { continue }
if ($file.Name -match "^(\d+)-(\d+)-(\d+)") { continue }
$exif = New-Object -TypeName system.drawing.bitmap -ArgumentList $file.FullName
$captureDate = MakeString $exif.GetPropertyItem(36867)
#Disposing object as soon as possible
$exif.Dispose()
$captureDate = ($captureDate -replace ":", '-').Substring(0,19)
$newFilename = $captureDate + " " + $file.Name.Trim()
$file.Name + " -> " + $newFilename
$file |Rename-Item -NewName $newFilename
}

Related

Uploading 2 files with same name to FTP using powershell script

I am a beginner at powershell script and I am stuck
I am trying to upload 2 xml files with the same name to FTP, but I am getting the following error
Exception calling "UploadFile" with "2" argument(s): "An
exception occurred during a WebClient request." At
C:\powershell\ExternalWidgets\upload-to-ftp.ps1:51 char:16
+ $webclient.UploadFile($uri.AbsoluteUri, $LocalPath)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : WebException`
Here is the script:
#SET CREDENTIALS
$credentials = new-object System.Net.NetworkCredential($user, $pass)
cd $target
$DirectoryContent = Get-ChildItem -Directory
foreach($item in $DirectoryContent){
cd $item
$currentFolderItems = Get-ChildItem
foreach( $subfolderItem in $currentFolderItems)
{
if ($subfolderItem.name -eq "package.json") {
$subItem = Get-ChildItem -Directory
foreach($subItem in $subItem)
{
if ($subItem.name -eq "coverage") {
$files = Get-ChildItem -Path $subItem
$n = 0
foreach ($file in $files)
{
#rename coverage file
if($file.Name -eq "cobertura-coverage.xml") {
$newFileName=$file.Name.Replace("cobertura-coverage.xml","cobertura-coverage$n.xml")
Rename-Item $file -NewName $newFileName
$newFileName
}
$n++
}
}
}
$webclient = New-Object System.Net.WebClient
$webclient.Credentials = New-Object
System.Net.NetworkCredential($user,$pass)
$uri = New-Object System.Uri($ftp + "/" + $folder)
#Delete files from FTP
# $fileUploaded =($uri + "\" + $newFileName)
# $fileUploaded
# Remove-Item $fileUploaded
$LocalPath =($target + "\" + $item + "\" + "coverage" + "\" +
$newFileName).Replace(".\", "").Replace('\', '/')
$webclient.UploadFile($uri, $LocalPath)
#cd..
}
}
cd ..
}
I also get an error when I want to rename one of the files. What step am I missing? Thank you

Test-Path - Illegal characters in path when using a variable

I m fairly new to PowerShell and I apologize in advance if this is a dumb question.
I am trying to construct a new destination/filename where I take the old filename and increment its prefix with +1
$destination = Split-Path -Path 'C:\Users\tom\Desktop\test\0_InstalledPrograms.log'
$file = split-path "C:\Users\tom\Desktop\test\0_InstalledPrograms.log" -Leaf
$array = $file -split '_'
$prefix = $array[0] + 1
$suffix = $array[1]
$newFile = $prefix + '_' + $suffix
$newFile = Out-String -InputObject $newFile
$destination = $destination + '\' + $newFile
Test-Path $destination
Test-Path : Illegal characters in path.
At C:\Users\tom\Desktop\incrementFileName.ps1:18 char:1
+ Test-Path $destination
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (C:\Users\lgranc...dPrograms.log
:String) [Test-Path], ArgumentException
+ FullyQualifiedErrorId : ItemExistsArgumentError,Microsoft.PowerShell.Commands.TestPathCommand
False
This statement:
$newFile = Out-String -InputObject $newFile
adds a new line (CR+LF) to the string, and is completely unnecessary ($newFile is already a string).
Remove that line and it'll work :)
You can do it easily as follows:
$file = "C:\Users\tom\Desktop\test\0_InstalledPrograms.log"
$splittedName = (Split-Path $file -leaf).split('_')
$newFileName = [string]([int]$splittedName[0] + 1) +'_'+ $splittedName[1]
Move-Item -Path $file -Destination (Join-Path (Split-path $file) -ChildPath $newFileName)

Powershell Outputting a Log File

Hello I am new scripting, I am tasked with creating a script that will be deleting a file from specific folders which will be deployed through SCCM onto many computers.
The problem is I want to output the log file saying either:
"<ComputerName> File Terminated"
"<ComputerName> File Not terminated"
Here is what I have so far:
$users = "C:\Users"
$logFile = "C:\TTS\Logs\GoogleTerm.log"
$source = "\AppData\Roaming\Google"
$exclude = "Default"
$input = get-ChildItem -Path $users
foreach ($folder in $input) {
if ($exclude -notcontains $folder.Name) {
Remove-Item -Path ($Users + "\" + $folder.Name + $source) -recurse -force
}
}
echo "Google Terminated on:"$env:computername >> $logfile
Added an else to your if to handle both outcomes, and then using Add-Content instead of echo:
foreach ($folder in $input) {
if ($exclude -notcontains $folder.Name) {
Remove-Item -Path ($Users + "\" + $folder.Name + $source) -recurse -force
Add-Content $logfile "$env:computername File Terminated"
}
else {
Add-Content $logfile "$env:computername File Not Terminated"
}
}
Add-Content $logfile "Google Terminated on: $env:computername"
This was my successfull solution, thank you guys for the assistance!
$users = "C:\Users"
$logFile = "C:\TTS\Logs\GoogleTerm.log"
$exclude = "Default"
$input = get-ChildItem -Path $users
foreach ($folder in $input) {
if ($exclude -notcontains $folder.Name) {
if (Test-Path ($Users + "\" + $folder.Name + $source)){
Remove-Item -Path ($Users + "\" + $folder.Name + $source) -recurse -force
Add-Content $logFile "Google Terminated on: $env:computername UserName:$folder "
}
else{
Add-Content $logFile "Google Already Terminated on:$env:computername UserName:$folder "
}
}
else{
Add-Content $logFile "Not Terminated on: $env:computername Username:$folder"
}
}

The property 'Name' cannot be found on this object. Verify that the property exists

My script is working, but I'm getting this error:
The property 'Name' cannot be found on this object. Verify that the property exists.
I'm looping to copy folders. Any idea what is going on?
$source50 = "c:\folder\"
$destination50 = "c:\folder1\"
for ($i = 1; $i -le 7; $i++) {
$d = ((Get-Date).AddDays( + $i))
$d2 = $d.ToString("yyyy-MM-dd")
$v = Get-ChildItem $source50 -Recurse -Include "$d2"
foreach ($file in $v)
{
if ( Test-Path $v.FullName)
{
if (-not (Test-Path -Path $destination50$d4)){
New-Item -ItemType directory -Path $destination50$d4
}
Write-Output "Copy ok " $v.FullName
$bd= Copy-Item $v.FullName -Destination $destination50$d4
break
}
}
The code is giving the error:
ok C:\folder\2017-12-27
ok C:\folder\2017-12-28
The property 'Name' cannot be found on this object. Verify that the property
exists.
At line:16 char:11
+ if ($v.Name -eq $d2) {
+ ~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], PropertyNotFoundException
+ FullyQualifiedErrorId : PropertyNotFoundStrict
ok C:\folder\2017-12-30
The property 'Name' cannot be found on this object. Verify that the property
exists.
the $v.Name throw exception because its an array object and not "System.IO." that has the property Name.
try using this code:
$source50 = "c:\folder\"
$destination50 = "c:\folder1\"
for ($i = 1; $i -le 7; $i++)
{
$d = ((Get-Date).AddDays( + $i))
$d2 = $d.ToString("yyyy-MM-dd")
$v = Get-ChildItem $source50 -Recurse -include "$d2"
foreach($file in $v)
{
if ($file.Name -eq $d2)
{
Copy-Item $file.FullName -Destination $destination50 -Force
Write-Host "ok" $file.FullName | Out-File -FilePath c:\folder\logggg.txt
}
}
}

Powershell Copying Files Script

I am trying to copy, and rename multiple files to miltiple folders. The folders will be labeled sequentially like the files. For example I need to copy Reports.txt change the name to Reports_NW01_20120219.txt to a folder called NW01 then the same process for NW02-NW18. The folder and file names increase by 1. I am new to powershell so please spare me. I have pasted what I have below. I am attempting to read in the date and then append it to the file name. I am at a complete loss now. So any help is appreciated:
$date = read-host "Enter date of the report YYYYMMDD"
write-host $date
for ($Counter = 1; $Counter -le 1; $Counter++)
{
#Destination for files
$DropDirectory = "C:\Users\dh0520\Documents\Powershell Staging\"
#Current Location of the files
$file = Get-ChildItem -Path "C:\Users\dh0520\Documents\Powershell Test\NW01\Reports.txt"
if ($Counter -lt 10) {
$Destination = $DropDirectory+'NW0' + $Counter
$file = Get-ChildItem -Path "C:\Users\dh0520\Documents\Powershell Test\NW0" + $Counter + "\Reports.txt"
Copy-Item $file.FullName ($Destination + $file.BaseName + "_NW0" + $Counter + "_" + $date +".txt")
}
If ($Counter -ge 10) {
$Destination = $DropDirectory+'NW' + $Counter
$file = Get-ChildItem -Path "C:\Users\dh0520\Documents\Powershell Test\NW" + $Counter + "\Reports.txt"
Copy-Item $file.FullName ($Destination + $file.BaseName + "_NW" + $Counter + "_" + $date +".txt")
}
}
I assume you are getting errors with the get-childItem. It is because you cant build the path like that. Try it this way:
$file = Get-ChildItem -Path "C:\test\NW0$($Counter)\Reports.txt"
and this way:
$file = Get-ChildItem -Path "C:\test\NW$($Counter)\Reports.txt"