Powershell Delete used Variables - powershell

I appear to have a problem deleting used variables with are locking files, before reusing the same path/file.
First I am declaring a path for my SQL process to write each line into a database:
$Files = get-childitem $Folder -Include *COMMON* -Recurse;
Next append the file then move it, but the appending the file name fails:
Get-ChildItem –Path $Folder where-object { $_.Name -like "*COMMON*" }| rename-item -newname {$DateTime + $_.Name}
Using something line:
$Files.delete()
Before attempting to access the path gives me
Exception calling "Delete" with "0" argument(s): "The process cannot access the file because it is being used by another process."
At line:1 char:1
+ $Files.Delete()
If I check the file, it is locked by Powershell...
Are there any solutions to this? I need to process the files in the folder then rename and move them all in one execution of my script... :(

$datetime is not defined in the code that you've posted.
If you've defined it elsewhere, using code such as $datetime = get-date, then the append operation will fail because $datetime is not a string. By executing $datetime.gettype() you would see it is a System.DateTime object. In PS two easy ways to convert an object into a string are 1) to interpolate it: "$datetime$($_.name)" or 2) use ToString(): $datetime.tostring() + $_.name

Related

null-valued expression error in simple powershell script

I have a small powershell script that looks in a patch for all files that contain a string and then replace that string.
Im sure this worked last week so im very confused why its now not working.
$filePath = "C:\my\file\path*"
# Get the files from the folder and iterate using Foreach
Get-ChildItem $filePath -Recurse | ForEach-Object {
# Read the file and use replace()
(Get-Content $_).Replace('oldString','NewString') | Set-Content $_
}
Im getting two errors i think, the first is:
Get-Content : Access to the path 'C:\my\file\path\YYY' is denied.
YYY is a folder in my path and im running the script as administrator, i was running as my own user who i confirmed has full access to this path.
The second is:
You cannot call a method on a null-valued expression.
Im guessing its the $_ but im really not sure. Ive tried replacing it with different name but no luck.
The You cannot call a method on a null-valued expression error is coming from calling the replace method when the result of Get-Content $_ is null.
This can happen for a few reasons:
First, inside of your ForEach-Object script block, $_ will essentially return the same value as $_.name which does not contain the full path to the folder or file being processed. Depending on the value of the working directory,$PWD, when you execute this code this could result in a bad file or folder path.
To address issues with the working directory try using $_.FullName. For debugging you can also write that value to the terminal to confirm where it is looking.
The issue could also be that the file has no contents. If the file is empty then the result of Get-Content will be $null.
Also attempting to get the content of a folder will result in an "access denied" error, after which the result of (get-content $_) will also be $null, resulting in the null error you received.
To summarize:
Double check your working directory.
Consider using $_.FullName.
Consider adding code to avoid calling Get-Content on folders.
Here is an example which I tested with several nested folders, some of which contained empty files and others which contained files with contents:
Get-ChildItem C:\testFolder -File -Recurse | ForEach-Object{
#this write host is just for debugging, to see what the file path is
Write-Host $_.FullName
$fileContents = Get-Content $_.FullName
if($fileContents -ne $null){
$fileContents.replace('oldString','newString') | Set-Content $_.FullName
}
}

Powershell Script Check if folder doesnt contain random file other than specific file, It will Create New File

Im quite new to powershell script. Currently I wan to find the files in the path, if the path doesnt contain .txt file, it will create a new text file. Is there anyway i can do that?
I've tried with script below but it came out with the error parameter eq not found
if (Test-Path $path -Exclude *.bak -eq false)
We can use Get-ChilItem as our base here and pass the properties we are searching for such as the the .txt extension and do something with it. Using the if conditional statement, we can accomplish this like so:
#assign the objects returned from Get-ChildItem to $loc
$Loc = Get-ChildItem C:\users\Abraham
#Check to see if the extension is found using a -notcontains conditional operator
#(against the property of .extension of each returned object (paths))
#See here https://www.computerperformance.co.uk/powershell/contains/
if($Loc.extension -notcontains ".txt"){
#this is our "DO", where the condition was met above
#so we will create the text file named "MyText"
#(by passing the "fullname" property which contains the full path of the objects in $Loc.)
New-Item -Path $Loc.fullname -Name MyText.txt}
What we're doing here is referencing the properties of the returned objects from Get-ChildItem by using whats called, "Dot Notation": $loc.Name, $loc.fullname, $loc.LastWriteTime, etc
You can get a list of the properties and methods(stuff you can do to the object(s)) by piping any cmdlet to Get-Member. Get-ChildItem | GM #GM is an alias for Get-Member.
Do you mean you want to use Test-Path to check if a certain file is present and if not create it?
Something like this then perhaps?
$path = 'D:\Test'
if (!(Test-Path -Path "$path\*" -Filter '*.txt' -PathType Leaf)) {
$null = New-Item -Path $path -Name ('Test_{0:ddMMyyyy}.txt' -f (Get-Date))
}

Method invocation failed because [System.IO.DirectoryInfo] does not contain a method named 'replace'

I have a few hundred folders to represent all my subnets.
Example, for the folder name
172.31.3.250_29
represents the subnet
172.31.3.250/29
Because you can't have "/" in windows folder names.
I have about 250 of these folders.
I am writing a powershell script that will take each folder name and run a script against the "subnet" that the folder represents, and dump a log in that folder.
However, I'm stuck on a simple issue.
I have successfully been able to extract the name of all sub folders in a folder
I need to replace the "_" with "/" to denote proper subnet format for my script.
$NmapFolder = Get-ChildItem -Path "U:\nmap reports\Nmap Subnet Scans\August2019" -Recurse -Directory -Force -ErrorAction SilentlyContinue
$data = ForEach ($items in $NmapFolder){
$items = $items.replace('_','/')
#eventually will have nmap script logic
#eventually will have "wait for nmap done" check before proceeding with next folder/subnet
write-host $items
}
Which produces the error...
Method invocation failed because [System.IO.DirectoryInfo] does not contain a method named 'replace'.
At line:6 char:1
+ $items = $items.replace('_','/')
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
Get-ChildItem returns a System.IO.DirectoryInfo or System.IO.FileInfo object, not a string. Since you specified -Directory, you will first need to convert the DirectoryInfo objects to strings
One easy way to do this would be to change the first line of your code:
$NmapFolder = #( ( Get-ChildItem -Path "U:\nmap reports\Nmap Subnet Scans\August2019" -Recurse -Directory -Force -ErrorAction SilentlyContinue ).Name )
This will roll up the Name property of every returned DirectoryInfo object into an array of strings, which you can then iterate over. However, if you have a deeper directory structure to traverse (I assume you might since you are using -Recurse), you may want to consider making use of piping your Get-ChildItem command into Resolve-Path -Relative, and parsing your subnet folder name from that array of strings, as it looks like eventually you may try writing something back into that folder from this script.

Powershell error copy-item cannot bind argument to parameter 'path' because it is null

I am rather new to Powershell and have a question regarding the error I'm receiving. After browsing through stack overflow I have found that users have made errors in spelling and the like and so I haven't found a suitable answer to my problem.
I have one script that runs a backup of some data and compresses it and stores it as:
yyyyMMddsometext.7z
I have another script to get the latest backup (if it was created) and copy it to another location
I am receiving an error
copy-item cannot bind argument to parameter 'path' because it is null
Does this mean that the file is non-existent or is it an error in any of the below?
$c = $textBox.Text
$a = (Get-Date).AddDays(-1).ToString($c)
$b = Get-ChildItem "C:\BackupsRP1" -Filter *.7z | Where-Object BaseName -like "*$a*"
Copy-Item $b -Destination "C:\Users\user\Desktop"
Above the code is a simple GUI for the user to input the date in the format yyyyMMdd and it will locate the file one less day than the user inputs and copy it to the location.
Thank you,
J
$b might contain multiple files or even non at all, depending what your filter finds.
The correct why to do it:
# This will copy each of the files that
Get-ChildItem "C:\BackupsRP1" -Filter *.7z | where BaseName -like "*$a*" | Copy-Item -Destination "C:\Users\user\Desktop" -PassThru
This will copy all items that match the filter and output the copied files to the console afterwards.
Also, make sure that $a really contains what you want. (I cannot know since I don't know what is in your textbox.)
You have to make sure the values in the variables are as expected, You can add logging for debugging this.
$c = $textBox.Text
$c > c:\temp\Debug.log
$a = (Get-Date).AddDays(-1).ToString($c)
$a >> c:\temp\Debug.log
$b = Get-ChildItem "C:\BackupsRP1" -Filter *.7z | Where-Object BaseName -like "*$a*"
$b >> c:\temp\Debug.log
Copy-Item $b.FullName -Destination "C:\Users\user\Desktop"
$b will contain FileInfo object, you have to select the fullname property(the full path of the file) from the object.

Powershell Move-Item from Import-CSV: Error - Could not find part of the path

I've been working on a script in Powershell to get paths from a CSV file and move those files at the corresponding path to a new destination elsewhere. often with a different filename.
I am using Version 5.0
For example:
Source Destination : C:\1\2\3\File.pdf, D:\3\7\8\9\FILE1.pdf
Now I used the following script and it was initially able to move some of the files:
Import-CSV "R:\MoveFiles.csv" -Delimiter "," -ErrorAction Stop | ForEach-Object{Move-Item -path $_.Source -Destination $_.Destination}
Although around half way through executing it started to return this error:
Move-Item : Could not find a part of the path. At line:1 char:238
+ ... Each-Object{Move-Item -Literalpath $.Source -Destination $.Destina ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : WriteError: (Q:\RECORDS\PRIV...-4-20_N1969.pdf:FileInfo) [Move-Item],
DirectoryNotFoundException
+ FullyQualifiedErrorId : MoveFileInfoItemIOError,Microsoft.PowerShell.Commands.MoveItemCommand
As far as I can tell there are no special characters that would prevent the path being found. If I replace Move-Item for Copy-Item it returns the same error. I have also checked the paths to see if they are true or not.
I am at my wits end with this. Not sure what else to try. I am after all a complete novice.
Thank you
NB: I worked out a solution to this issue. It would appear that the Move-Item cmdlet does not like creating directories.
Instead I made the directories first with New-Item -directories, getting the content from a text document where every line represented a path (no headers).
After creating empty directories first the original script worked as intended.
For anyone interested here is the directories script:
#CREATE DIRECTORIES FROM CSV
cd
$name = Get-Content ".\Create_New_Directories\Move_Directories_Test.txt"
Foreach ($_ in $name)
{
New-Item -Force -verbose -path $_ -Type Directory
}
Out-File ".\Create_New_Directories\Newoutput.txt"
Thank you everyone for your help.
To debug such cases, consider Move-Item's -WhatIf parameter. Like so,
... | ForEach-Object{Move-Item -whatif -path $_.Source -Destination $_.Destination}
This will print the intended operation, so you can double-check paths for any sheenigans.
What if: Performing the operation "Move File" on target "Item:
C:\Temp\SomeFile.xml Destination: C:\Temp\Somewhere\SomeFile.xml".
Not sure. But your error message indicates it's a write error of DirectoryNotFound.
So perhaps you should be making sure you have the perms on the target side and are not exceeding any character limits in the length of the path.
Some other things to consider/try:
Your CSV file should be in the format (the first line must be the headers):
Source,Destination
C:\1\2\3\SomeFile.pdf,D:\1\2\3\SomeFile.pdf
C:\1\2\3\SomeFile2.pdf,D:\1\2\3\SomeFile2.pdf
Also you are not santizing your input so if you made the CSV file in Excel you might have leading or trailing spaces. In that case either clean the file editing in Notepad or try $_.Source.trim() and $_.Destination.trim()
And like the other guy said the -whatif switch is useful and so is -verbose.
You might also try Move-Item -Force and/or opening powershell as an Administrator.
Good Luck! ;-)