Rename-Item throwing error when path contains '>' - powershell

When I try to rename a path that contains '<' or '>' i get the
Illegal characters in path error. Strangely Rename-Item can handle other special characters like '#'.
I refuse to belive that rename-item can't handle the '<' char. Does it needs to be escaped somehow?
I'm using the Get-FolderItem cmdlet instead of Get-ChildItem (due to pathlength restrictions on gci) and passing Rename-Item a object with a fullname prop like so
Edit: I'm a noob, it's › and not >
Rename-Item -LiteralPath $fileWithChar.FullName -NewName $newNameWithoutChar
Both $filleWithChar and $newNameWithoutChar are strings.
I've tried using both -path and literalPath and it still throws the error.

robocopy is a Unicode application on demand, see following Logging options switches:
/unicode : Display the status output as Unicode text
/UNILOG:file : Output status to Unicode Log file (overwrite)
/UNILOG+:file : Output status to Unicode Log file (append)
Below is improved Get-FolderItem.ps1 script. Pay your attention to changes:
line 135 $params.AddRange(#("/L", … ,"/R:0","/W:0"))
changed $params.AddRange(#("/L", … ,"/R:0","/W:0","/UNILOG:robolog.txt"))
line 158 Invoke-Expression $Script | ForEach {
changed Invoke-Expression $Script | Out-Null; Get-Content robolog.txt | ForEach {
Sample output proves Unicode awareness (some names are pretty nonsensical, sorry):
PS D:\PShell> . D:\Downloads\Get-FolderItem.ps1
PS D:\PShell> $x=Get-ChildItem -path "D:\bat\UnASCII Names\*" | Get-FolderItem
WARNING: D:\bat\UnASCII Names\ěščřžýáíé.txt is not a directory and will be skipped
PS D:\PShell> $x.FullName
D:\bat\UnASCII Names\MathBoldScript (𝓜𝓪𝓽𝓱𝓑𝓸𝓵𝓭𝓢𝓬𝓻𝓲𝓹𝓽)\Mathematical Bold Script.txt
D:\bat\UnASCII Names\Türkçe (Türkiye)\çğüşöıĞÜİŞÇÖ\ĞÜİŞÇÖçğüşöı.txt
D:\bat\UnASCII Names\‹angles›\‹angles›.txt
PS D:\PShell>
Improved script uses an auxiliary file:
Function Get-FolderItem {
<#
.SYNOPSIS
Lists all files under a specified folder regardless of character limitation on path depth.
.DESCRIPTION
Lists all files under a specified folder regardless of character limitation on path depth.
.PARAMETER Path
The type name to list out available constructors and parameters
.PARAMETER Filter
Optional parameter to specify a specific file or file type. Wildcards (*) allowed.
Default is '*.*'
.PARAMETER ExcludeFile
Exclude Files matching given names/paths/wildcards
.PARAMETER MaxAge
Exclude files older than n days.
.PARAMETER MinAge
Exclude files newer than n days.
.EXAMPLE
Get-FolderItem -Path "C:\users\Administrator\Desktop\PowerShell Scripts"
LastWriteTime : 4/25/2012 12:08:06 PM
FullName : C:\users\Administrator\Desktop\PowerShell Scripts\3_LevelDeep_ACL.ps1
Name : 3_LevelDeep_ACL.ps1
ParentFolder : C:\users\Administrator\Desktop\PowerShell Scripts
Length : 4958
LastWriteTime : 5/29/2012 6:30:18 PM
FullName : C:\users\Administrator\Desktop\PowerShell Scripts\AccountAdded.ps1
Name : AccountAdded.ps1
ParentFolder : C:\users\Administrator\Desktop\PowerShell Scripts
Length : 760
LastWriteTime : 4/24/2012 5:48:57 PM
FullName : C:\users\Administrator\Desktop\PowerShell Scripts\AccountCreate.ps1
Name : AccountCreate.ps1
ParentFolder : C:\users\Administrator\Desktop\PowerShell Scripts
Length : 52812
Description
-----------
Returns all files under the PowerShell Scripts folder.
.EXAMPLE
$files = Get-ChildItem | Get-FolderItem
$files | Group-Object ParentFolder | Select Count,Name
Count Name
----- ----
95 C:\users\Administrator\Desktop\2012 12 06 SysInt
15 C:\users\Administrator\Desktop\DataMove
5 C:\users\Administrator\Desktop\HTMLReportsinPowerShell
31 C:\users\Administrator\Desktop\PoshPAIG_2_0_1
30 C:\users\Administrator\Desktop\PoshPAIG_2_1_3
67 C:\users\Administrator\Desktop\PoshWSUS_2_1
437 C:\users\Administrator\Desktop\PowerShell Scripts
9 C:\users\Administrator\Desktop\PowerShell Widgets
92 C:\users\Administrator\Desktop\Working
Description
-----------
This example shows Get-FolderItem taking pipeline input from Get-ChildItem and then saves
the output to $files. Group-Object is used with $Files to show the count of files in each
folder from where the command was executed.
.EXAMPLE
Get-FolderItem -Path $Pwd -MinAge 45
LastWriteTime : 4/25/2012 12:08:06 PM
FullName : C:\users\Administrator\Desktop\PowerShell Scripts\3_LevelDeep_ACL.ps1
Name : 3_LevelDeep_ACL.ps1
ParentFolder : C:\users\Administrator\Desktop\PowerShell Scripts
Length : 4958
LastWriteTime : 5/29/2012 6:30:18 PM
FullName : C:\users\Administrator\Desktop\PowerShell Scripts\AccountAdded.ps1
Name : AccountAdded.ps1
ParentFolder : C:\users\Administrator\Desktop\PowerShell Scripts
Length : 760
Description
-----------
Gets files that have a LastWriteTime of greater than 45 days.
.INPUTS
System.String
.OUTPUTS
System.IO.RobocopyDirectoryInfo
.NOTES
Name: Get-FolderItem
Author: Boe Prox
Date Created: 31 March 2013
Version History:
Version 1.5 - 09 Jan 2014
-Fixed bug in ExcludeFile parameter; would only work on one file exclusion and not multiple
-Allowed for better streaming of output by Invoke-Expression to call the command vs. invoking
a scriptblock and waiting for that to complete before display output.
Version 1.4 - 27 Dec 2013
-Added FullPathLength property
Version 1.3 - 08 Nov 2013
-Added ExcludeFile parameter
Version 1.2 - 29 July 2013
-Added Filter parameter for files
-Fixed bug with ParentFolder property
-Added default value for Path parameter
Version 1.1
-Added ability to calculate file hashes
Version 1.0
-Initial Creation
#>
[cmdletbinding(DefaultParameterSetName='Filter')]
Param (
[parameter(Position=0,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)]
[Alias('FullName')]
[string[]]$Path = $PWD,
[parameter(ParameterSetName='Filter')]
[string[]]$Filter = '*.*',
[parameter(ParameterSetName='Exclude')]
[string[]]$ExcludeFile,
[parameter()]
[int]$MaxAge,
[parameter()]
[int]$MinAge
)
Begin {
$params = New-Object System.Collections.Arraylist
$params.AddRange(#("/L","/S","/NJH","/BYTES","/FP","/NC","/NDL","/TS","/XJ","/R:0","/W:0","/UNILOG:robolog.txt"))
If ($PSBoundParameters['MaxAge']) {
$params.Add("/MaxAge:$MaxAge") | Out-Null
}
If ($PSBoundParameters['MinAge']) {
$params.Add("/MinAge:$MinAge") | Out-Null
}
}
Process {
ForEach ($item in $Path) {
Try {
$item = (Resolve-Path -LiteralPath $item -ErrorAction Stop).ProviderPath
If (-Not (Test-Path -LiteralPath $item -Type Container -ErrorAction Stop)) {
Write-Warning ("{0} is not a directory and will be skipped" -f $item)
Return
}
If ($PSBoundParameters['ExcludeFile']) {
$Script = "robocopy `"$item`" NULL $Filter $params /XF $($ExcludeFile -join ',')"
} Else {
$Script = "robocopy `"$item`" NULL $Filter $params"
}
Write-Verbose ("Scanning {0}" -f $item)
Invoke-Expression $Script | Out-Null
Get-Content robolog.txt | ForEach {
Try {
If ($_.Trim() -match "^(?<Size>\d+)\s(?<Date>\S+\s\S+)\s+(?<FullName>.*)") {
$object = New-Object PSObject -Property #{
ParentFolder = $matches.fullname -replace '(.*\\).*','$1'
FullName = $matches.FullName
Name = $matches.fullname -replace '.*\\(.*)','$1'
Length = [int64]$matches.Size
LastWriteTime = [datetime]$matches.Date
Extension = $matches.fullname -replace '.*\.(.*)','$1'
FullPathLength = [int] $matches.FullName.Length
}
$object.pstypenames.insert(0,'System.IO.RobocopyDirectoryInfo')
Write-Output $object
} Else {
Write-Verbose ("Not matched: {0}" -f $_)
}
} Catch {
Write-Warning ("{0}" -f $_.Exception.Message)
Return
}
}
} Catch {
Write-Warning ("{0}" -f $_.Exception.Message)
Return
}
}
}
}

Related

Resolve-Path: cannot find path because it does not exist. error in powershell

Firstly: what My code does it counts the number of duplicate files in a particular path entered by the user.
It does this by first calculating which files have the same length. and from the files that have the same length, it checks which files also have the same hash. And then in the end I am making an object which contains the information that I need to print in a table.
Problem:
In my code,
I am getting an error which I am pretty sure is coming from the Get-FileHash commandlet.
when I ctrl + click on the link that is given in the "At" section of the error, It takes me to the Get-FileHash commandlet utility in powershell
C: >WIndows > system32 > WindowsPowershell > v1.0 > Modules > Microsoft.Powershell.Utility > Microsoft.Powershell.Utility.psm1 > Get-FileHash{}
the error only comes up for some .msg and .pdf files
the code works perfectly fine on a path with lesser files.
Here is the Error:
Resolve-Path : Cannot find path '<path of File>' because it does not exist.
At C:\Windows\system32\WindowsPowerShell\v1.0\Modules\Microsoft.PowerShell.Utility\Micro
+ ... $pathsToProcess += Resolve-Path -LiteralPath $LiteralPath | Forea ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (<nameOfFile>:String)
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.ResolvePathComm
And here is the code:
#taking the input of the user!
$pathInputByUser = Read-Host ("Please Enter the Path where you want to check for duplicate files")
#Accessing the path entered by the user
cd $pathInputByUser
write-host ("Loading: Please Wait! This can take a upto 2.5 hrs") -ForegroundColor Green
$Stopwatch = [System.Diagnostics.Stopwatch]::StartNew();
$totalNumOfFiles = 0;
#the variable "filesGroupedAccordingToLength" contains all the files grouped according to their size. files with same size , are in the same group
$filesGroupedAccordingToLength = Get-ChildItem -Recurse -File `
| Group-Object -Property Length
#below calculating the number of total Files that we have found till now
$totalNumOfFiles = $filesGroupedAccordingToLength | Measure-Object -Property Count -Sum | % { $_.sum };
#the below variable "filesWhichHaveSameLengths" contains group of files that have the same size as some other file
$filesWhichHaveSameLengths = $filesGroupedAccordingToLength | ? { $_.Count -gt 1 } `
| % { $_.Group }
#the below variable "hash" contains group of files that have the same hash as some other file
$groupedFilesWithSameHash = $filesWhichHaveSameLengths | Get-FileHash `
| Group-Object -Property Hash `
| ? { $_.Count -gt 1 }
$numOfDuplicates= 0;
$calculatingCountDuplicates= $groupedFilesWithSameHash| Select-Object -ExpandProperty Count| %{ $numOfDuplicates= $numOfDuplicates + ($_ - 1) };
"The number of duplicate files are: $numOfDuplicates"
#the below variables contains hash of duplicate files
$hashOfDuplicateFiles= $groupedFilesWithSameHash | % { $_.Group }
#making objects to be able to display result as a table
$res= #();
$hashValue=0;
foreach ($tuple in $hashOfDuplicateFiles) {
foreach ($var in $filesWhichHaveSameLengths) {
if ($var.FullName -eq $tuple.Path) {
$obj= new-object psobject -Property #{
LastWriteTime = $var.LastWriteTime
Name = $var.Name
length = $var.length
FullName = $var.FullName
hash = $tuple.Hash
RelativePath = $var.PSPath.Replace("Microsoft.PowerShell.Core\FileSystem::F:\", "")
}
if($tuple.Hash -ne $hashValue){
$obj|Add-Member -NotePropertyName U/D -NotePropertyValue "Unikat"
$res= $res+$obj;
$hashValue= $tuple.Hash;
}
else{
$obj|Add-Member -NotePropertyName U/D -NotePropertyValue "Duplikat"
$res= $res+$obj;
}
}
}
}
$res | Format-Table -AutoSize -Property Name, U/D, LastWriteTime, hash, length, RelativePath |Out-File -FilePath C:\Users\Public\Documents\Ebrahim_iris\DuplicateFinderTool\testLog.txt
"the number of total files is : $totalNumOfFiles"
"The number of duplicate files are: $numOfDuplicates"
"The number of unique files are: $($totalNumOfFiles-$numOfDuplicates)"
$Stopwatch.Stop();
"The script ran for: $($Stopwatch.Elapsed.TotalMinutes) minutes"
Any advice to remove this error will be appreciated.

Modifying the Powershell calculated property with directory size

I am trying to modify the below script to add one more column 'Directory size' so that it shows the total directory size for NTFS share.
Function Get-SmbSharePermission([String]$ComputerName = '.') {
$Shares = #{}
Get-WmiObject -Class Win32_Share -ComputerName $ComputerName | ForEach-Object {$Shares[$_.Name] = $_.Path}
Get-WmiObject -Class Win32_LogicalShareSecuritySetting -ComputerName $ComputerName | ForEach-Object {
$Name = $_.Name
$_.GetSecurityDescriptor().Descriptor.DACL | Select-Object -Property `
#{n='ComputerName'; e={$ComputerName}},
#{n='Name'; e={$Name}},
#{n='Path'; e={$Shares[$Name]}},
#{n='Account'; e={"$($_.Trustee.Domain)\$($_.Trustee.Name)".Trim('\')}},
#{n='Permission'; e={
Switch ($_.AccessMask) {
0x001F01FF {'Full'}
0x001301BF {'Change'}
0x001200A9 {'Read'}
default {"0x$($_.ToString('X8'))"}
}
}},
#{n='Type'; e={If ($_.AceType) {'Deny'} Else {'Allow'}}}
}
}
Get-SmbSharePermission | ogv
The script above does almost everything, except the total size of the directory.
How can I integrate it with the below function that can show the directory size?
$scriptBlock = {
param ([string]$Path,
[string]$GroupName)
# Get the total directory number and file counts
# the '/L' [for List] tells robocopy to not do anything, just list what it _would_ do
# /E :: copy subdirectories, including Empty ones.
# /L :: List only - don't copy, timestamp or delete any files.
# /NFL :: No File List - don't log file names.
# /NDL :: No Directory List - don't log directory names.
# /NP :: No Progress - don't display percentage copied.
$RC_Results = robocopy $Path 'NULL' /L /E /NP /NFL /NDL
# check to see if i forgot to re-enable the robocopy run [*blush*]
if ($RC_Results.Count -eq 0)
{
Write-Warning "You need to remove the `#` on line 2."
break
}
# the summary table is the first 5 of the last 7 lines
$RC_Summary = $RC_Results |
Select-Object -Last 7 |
Select-Object -First 5
# add a 'Type' column header to the 1st line
$RC_Summary[0] = 'Type' + $RC_Summary[0]
# add placeholders for the blank 'Times' [last line] columns
$RC_Summary[-1] = $RC_Summary[-1].
Insert(39, 'N/A').
Insert(49, 'N/A')
$NewRC_Summary = #()
# line cleanup
foreach ($Line in $RC_Summary)
{
# remove leading and trailing spaces
$NewLine = $Line.Trim()
# remove ':' that are NOT in time spans
$NewLine = $NewLine.Replace(' :', '')
# replace multi-spaces with singletons
$NewLine = $NewLine -replace '\s{2,}', ' '
# remove space between number and unit letter [bytes, kilobytes, etc.]
# 1.22 m >> 1.22m
$NewLine = $NewLine -replace '(\d)\s([bkmg])', '$1$2'
# replace remaining spaces with a comma
$NewLine = $NewLine.Replace(' ', ',')
# add to the new summary collection
$NewRC_Summary += $NewLine
}
$RC_SummaryTable = #{ }
foreach ($Item in ($NewRC_Summary | ConvertFrom-Csv))
{
$RC_SummaryTable.Add($Item.Type, $Item.Total)
}
[PSCustomObject] #{
DirPath = $Path
DirCount = "{0}" -f $RC_SummaryTable['Dirs']
FileCount = "{0}" -f $RC_SummaryTable['Files']
TotalSize = "{0}" -f $RC_SummaryTable['Bytes']
}
}
Update
The suggested code by Cpt. Whale below shows the whole disk drive size not each directories under Path:
I prefer to use volume information rather than doing a complete file listing via robocopy. I'm using the newer CimInstance powershell cmdlets here to get the volume information via Get-SmbShare:
Function Get-SmbSharePermission([String]$ComputerName = '.') {
# Create a cim session to use later, and get a list of the remote share objects:
$cim = New-CimSession -ComputerName $Computername
$shares = Get-SmbShare -CimSession $cim | Where Name -NotIn 'print$','IPC$'
# Iterate through each share
Foreach ($Share in $shares) {
# Skip shares without volume info (not file shares, e.g. shared printers)
if(!$Share.Volume){continue}
# Get the assoviated volume size
$Volume = Get-Volume -CimSession $cim -UniqueId $Share.Volume
# Get the access information, and format
Get-SmbShareAccess -CimSession $cim -Name $Share.Name | Select `
#{n='ComputerName'; e={$ComputerName}},
#{n='Name'; e={$Share.Name}},
#{n='Path'; e={$Share.Path}},
#{n='Account'; e={$_.AccountName}},
#{n='Permission'; e={$_.AccessRight}},
#{n='Type'; e={$_.AccessControlType}},
#{n='Drive'; e={$Volume.DriveLetter}},
#{n='TotalSize'; e={[String][Math]::Round($Volume.Size/1GB)+' GB'}},
#{n='FreeSpace'; e={[String][Math]::Round($Volume.SizeRemaining/1GB)+' GB'}}
}
}
# Output:
Get-SmbSharePermission | ft
ComputerName Name Path Account Permission Type Drive TotalSize FreeSpace
------------ ---- ---- ------- ---------- ---- ----- --------- ---------
RemoteServer ADMIN$ C:\WINDOWS BUILTIN\Administrators Full Allow C 100 GB 20 GB
RemoteServer ADMIN$ C:\WINDOWS BUILTIN\Backup Operators Full Allow C 100 GB 20 GB
RemoteServer ADMIN$ C:\WINDOWS NT AUTHORITY\INTERACTIVE Full Allow C 100 GB 20 GB

Getting a specific process id from a powershell output

Hi I'm new to powershell scripting and I would like to retrieve a specific process id based on the file's hash. However I can only get either a table with the hash value or a table with the id,process name and path
$ps = Get-Process | Select-Object -Property Id,ProcessName,Path
$hashlist = Get-FileHash(Get-Process|Select-Object -ExpandProperty Path) -Algorithm MD5
Is it possible for me to merge the two tables together so that I can get a view of Id,ProcessName and Hash using the path to link them together?
EDIT: totally different approach due to new information from comment
I don't think it is so easy to identify malware with a file MD5 hash.
Modern AntiVirusSoftware uses heuristics to overcome the problem of mean malware which includes random data and also obfuscates it's origin.
## Q:\Test\2018\11\11\SO_53247430.ps1
# random hex string replace with your malware signature
$MalwareMD5Hash = 'D52C11B7E076FCE593288439ABA0F6D4'
Get-Process | Where-Object Path | Select-Object ID,Path | Group-Object Path | ForEach-Object {
if ($MalwareMD5Hash -eq (Get-FileHash $_.Name -Alg MD5).Hash){
##iterate group to kill all processes matching
ForEach ($PID in $_.Group.ID){
Stop-Process -ID $PID -Force -WhatIF
}
}
$_.Name | Remove-Item -Force -WhatIf # to delete the physical file.
}
As I suggested in my comment:
$HashList = [ordered]#{}
Get-Process |Where-Object Path | Select-Object Path |Sort-Object Path -Unique | ForEach-Object {
$HashList[$_.Path]=(Get-FileHash $_.Path -Alg MD5).Hash
## or the reverse, the hash as key and the path as value
# $HashList[(Get-FileHash $_.Path -Alg MD5).Hash]=$_.Path
}
$Hashlist | Format-List
Shorted sample output
Name : C:\Program Files\Mozilla Firefox\firefox.exe
Value : BFE829AB5A4B729EE4565700FC8853DA
Name : C:\WINDOWS\Explorer.EXE
Value : E4A81EDDFF8B844D85C8B45354E4144E
Name : C:\WINDOWS\system32\conhost.exe
Value : EA777DEEA782E8B4D7C7C33BBF8A4496
Name : C:\WINDOWS\system32\DllHost.exe
Value : 2528137C6745C4EADD87817A1909677E
> $hashlist['C:\WINDOWS\Explorer.EXE']
E4A81EDDFF8B844D85C8B45354E4144E
Or with the reversed list
> $hashlist['E4A81EDDFF8B844D85C8B45354E4144E']
C:\WINDOWS\Explorer.EXE

PowerShell New-Item output is inconsistent - Why?

I am getting different out for the same powershell command and I am not sure why.
When this runs within a function, I get output 1 and when I run by itself I get output2
New-Item -Path C:\DEPL\nichdwww\deployments\Full\bob3 -type directory
Output 1
PSPath : Microsoft.PowerShell.Core\FileSystem::C:\DEPL\nichdwww\deployments\Full\bob3
PSParentPath : Microsoft.PowerShell.Core\FileSystem::C:\DEPL\nichdwww\deployments\Full
PSChildName : bob3
PSDrive : C
PSProvider : Microsoft.PowerShell.Core\FileSystem
PSIsContainer : True
Name : bob3
Parent : Full
Exists : True
Root : C:\
FullName : C:\DEPL\nichdwww\deployments\Full\bob3
Extension :
CreationTime : 6/23/2015 2:14:39 PM
CreationTimeUtc : 6/23/2015 6:14:39 PM
LastAccessTime : 6/23/2015 2:14:39 PM
LastAccessTimeUtc : 6/23/2015 6:14:39 PM
LastWriteTime : 6/23/2015 2:14:39 PM
LastWriteTimeUtc : 6/23/2015 6:14:39 PM
Attributes : Directory
BaseName : bob3
Mode : d----
Output 2
Directory: C:\DEPL\nichdwww\deployments\Full
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 6/23/2015 2:45 PM bob3
Here is the function
function ArchiveFullSolution($wsp)
{
$ParentPath=Split-Path $wsp.DirectoryName -Parent
$FullPath=$ParentPath+'\Full\'
$Fullfilename=$FullPath+$wsp.Name
#$Fullfilename
#does file exist
if(Test-Path -path $Fullfilename)
{
#Make Full Archive folder
#$script:Makefolder
if($script:Makefolder)
{
#does folder exists
$DayFormat=Get-Date -f yyyy-MM-dd
if(Test-Path -path $FullPath$DayFormat)
{
write-host "folder $FullPath$DayFormat exists"
$DayTimeFormat=Get-Date -f yyyy-MM-dd-hh-mm
write-host "Creating folder $FullPath$DayTimeFormat"
New-Item -Path $FullPath$DayTimeFormat -type directory
$script:Makefolder=$false
$script:FullArchivePath=$FullPath+$DayTimeFormat
}
else
{
write-host "no folder exists"
write-host "Creating folder $FullPath$DayFormat"
New-Item -Path $FullPath$DayFormat -type directory
$script:Makefolder=$false
$script:FullArchivePath=$FullPath+$DayFormat
}
}
#move file into archive
Move-Item $Fullfilename $script:FullArchivePath
write-host "Moving file $($Fullfilename) to $FullArchivePath"
}
#copy file into full
Copy-Item $wsp.FullName $FullPath
write-host "Copying file $($wsp.FullName) to $FullPath"
}
Check your function. Most likely it is outputting another object first. After the PowerShell F&O (formatting and output) engine sees one type of object it wants to format everything after that like that type. If it then sees another type of object, it will fall back to using Format-List IIRC.

recursive display is not showing right format

Something wrong with my IF-ELSE statement and my dumb brain cannot figure out what the heck it is!
If I run the below code on its own it shows each directory and files in there in the below format:
get-childitem E:\LogArchive -recurse | where-object {$_.lastwritetime -gt 60}
Format of output:
Directory: E:\LogArchive\W3SVC100
Mode LastWriteTime Length Name
---- ------------- ------ ----
----- 29/03/2007 15:03 663 ex070329.log.gz
----- 30/03/2007 15:44 860 ex070330.log.gz
----- 03/04/2007 13:41 354 ex070403.log.gz
----- 05/04/2007 14:00 704 ex070405.log.gz
----- 10/04/2007 17:56 921 ex070410.log.gz
----- 11/04/2007 14:55 987 ex070411.log.gz
----- 12/04/2007 15:12 539 ex070412.log.gz
However, when this is run in a code it shows as the below, WITHOUT all the folder structure and dates etc:
W3SVC100
W3SVC102
W3SVC105
W3SVC106
W3SVC1108492480
W3SVC112
W3SVC116
W3SVC118
W3SVC1209046175
W3SVC123110214
W3SVC1262336480
W3SVC127
W3SVC134
W3SVC134239081
W3SVC137
W3SVC139
W3SVC145
W3SVC147
W3SVC1499983181
W3SVC15
How do I get the first results when the below script is run - so show all the modified date, last write time etc . I am currently inputting a message to the user if no files are found in the date range then a message is displayed - however, if it did find anyfiles then display them as listed in the first output type.......
I actually think the fault is on this line but cannot figure out how to amend this:
if ( $runchilditem.lastwritetime -gt DateToCompare)
......In fact - I want to put the output to CSV - any ideas how I can do this?
CODE:
$path = Read-Host "Please enter the path of the folder yu wish to check - this will check sub-folders as well"
Write-Host "`n"
$days = Read-Host "Please enter in number of DAYS you wish to go back"
$DateToCompare = (Get-Date).AddDays(-$days)
$runningtrue = Get-ChildItem $path -Recurse | where-object {$_.lastwritetime -gt $DateToCompare}
Write-Host "`n"
$runchilditem = #(Get-ChildItem $path -Recurse)
if ( $runchilditem.lastwritetime -gt DateToCompare)
{
Write-Host "No Files Matching Date Criteria Found"
}
else
{
$runningtrue
}
If I understand your need, here is how I would do it:
$path = Read-Host 'Path'
[int]$dayDiff = Read-Host 'Number of days to go back'
$offset = $dayDiff * -1
$files = Get-ChildItem $path -Recurse | Where-Object{$_.LastWriteTime -gt (Get-Date).AddDays($offset)}
if(($files.Count -eq 0) -OR ($files -eq $null)){
'There are no files after {0} in {1}' -f (Get-Date).AddDays($offset), $path
}else{
$files
$files | Export-CSV C:\PATH\TO\FILE.csv -NoTypeInfo
}