Hello,
Some users synchronize their data with synctoy (computer <-> server). I just want to scan folders to find their synctoy files (synctoyxxxxx.dat) and compare its LastWrite Time to compare to de date of the day.
I have 2 problems now:
-1) Synctoy generate several .Dat files. I want to get the more recent. I easily found the command for this but it runs with a single directory. When it exists several subfolders containing .dat files, the script returns just the last one .dat file ! I want to return the more recent .dat file for each folder containing a .dat file and write-host (or log) "more recent file - directory" for each.
-2) How return the number of days beetwen today and the more recents .dat file ?
This is thmy script below (for 1 subfolder)
$PathFile = "\\network\Secteur Est"
$File = gci $PathFile -Include synctoy*.dat -Recurse -Force -ErrorAction SilentlyContinue |
Sort-Object {$_.lastwritetime} -Descending | Select-Object -First 1
I tried a lot of test with Foreach and If but more I try and more it seems to be difficult for me....
Thanks a lot for your answers..
Hey,
For question one, I think this would be solved by grouping the files by Directory. Then you can select the first one for each folder. This is what I am doing with the Group-Object Cmdlet.
For question two, use calculated properties, that is the '@{Name='DayDifference';Expression={((Get-Date).Date - $_.LastWriteTime.Date).TotalDays}}' portion of this one-liner
So try this code and see how it works out for you:
Get-ChildItem -Path $PathFile -Include synctoy*.dat -Recurse -Force -ErrorAction SilentlyContinue |
Sort-Object -Property LastWriteTime -Descending |
Group-Object -Property Directory | ForEach-Object {
$_.Group | Select-Object -First 1 | Select FullName,LastWriteTime,@{Name='DayDifference';Expression={((Get-Date).Date - $_.LastWriteTime.Date).TotalDays}}
}
GREAT !
Thanks !
What will be the method to link directories where there is a .dat file to e-mail addresses ?
I am not sure what you mean there? Do you want to email the list of directories that contain .dat files?
Hello Jaap ! I hope your week-end was good !
Each subfolder where I will find .dat files are named like this : V01, V02, V03, V04, etc... Each subfolder belong to a user. For exemple V01 belong to misterX@mydomain.com, V02 belong to misterY@mydomain.com, etc...
I would like send the result of the directory V01 to misterX@mydomain.com, V02 results to misterY@mydomain.com, etc...
Must I do a text file with e-amil adresses ?
I would create a csv file that contains the folder names and email addresses and have the script match on that. Something along the lines of:
The script returns this error message :
Split-Path : Impossible de lier l'argument au paramètre « Path », car il a la valeur Null.
Au niveau de C:\Scripts_PS\temporaire\Synctoy.ps1 : 16 Caractère : 33
+ $Basename = Split-Path -Path <<<< $_.Directory -Leaf
+ CategoryInfo : InvalidData: (:) [Split-Path], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.SplitPathCommand
Alright, so what do you see if you add $_ at line 16, make the line look like this:
$_;$Basename = Split-Path -Path $_.Directory -Leaf
Hi Jaap !
It returns
15/01/2013 10:34:39 27 \Secteur Est\V17
Au niveau de C:\Scripts_PS\temporaire\Synctoy.ps1 : 14 Caractère : 36
+ $_;$Basename = Split-Path -Path <<<< $_.Directory -Leaf
The same for each folder...
Hmmm, I am not sure how regional settings affect the property names of Get-ChildItem. Could you show me the output when you run the following command:
ls | gm -membertype Property
see below :
PS C:\Windows\system32> ls | gm -membertype Property
TypeName : System.IO.DirectoryInfo
Name MemberType Definition
---- ---------- ----------
Attributes Property System.IO.FileAttributes Attributes {get;set;}
CreationTime Property datetime CreationTime {get;set;}
CreationTimeUtc Property datetime CreationTimeUtc {get;set;}
Exists Property bool Exists {get;}
Extension Property string Extension {get;}
FullName Property string FullName {get;}
LastAccessTime Property datetime LastAccessTime {get;set;}
LastAccessTimeUtc Property datetime LastAccessTimeUtc {get;set;}
LastWriteTime Property datetime LastWriteTime {get;set;}
LastWriteTimeUtc Property datetime LastWriteTimeUtc {get;set;}
Name Property string Name {get;}
Parent Property System.IO.DirectoryInfo Parent {get;}
Root Property System.IO.DirectoryInfo Root {get;}
TypeName : System.IO.FileInfo
Directory Property System.IO.DirectoryInfo Directory {get;}
DirectoryName Property string DirectoryName {get;}
IsReadOnly Property bool IsReadOnly {get;set;}
Length Property long Length {get;}
I putted an expression :
Select LastWriteTime,@{Name='Jours de retard';Expression={((Get-Date).Date - _.LastWriteTime.Date).TotalDays}},@{Name='Secteur';Expression={$_.DirectoryName -replace '.+itinérants',''}}
that I finally replaced by :
Select Directory,LastWriteTime,@{Name='Jours de retard';Expression={((Get-Date).Date - $_.LastWriteTime.Date).TotalDays}}
Now it's running. The only problem is that in the body e-mail it returns the results in that form below :
with $msg.body = $_
@{Directory=\\myServer\Secteur Est\V02; LastWriteTime=01/15/2013 17:42:01; Jours de retard=27}
or
with $msg.body = $_ | fl
Microsoft.PowerShell.Commands.Internal.Format.FormatStartData Microsoft.PowerShell.Commands.Internal.Format.GroupStartData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.GroupEndData Microsoft.PowerShell.Commands.Internal.Format.FormatEndData
Depending on what kind of output you want you could use any of these examples:
msg.body = $_ | Format-List | Out-String
msg.body = $_ | Format-Table -Autosize | Out-String
msg.body = $_ | Out-String
Thanks Jaap.
Below is the final script :
$PathFile = \\server\itinérants
$NamesFolders = Import-Csv C:\tmp\NamesFolder.csv
Group-Object -Property Directory |
ForEach-Object {$_.Group | Select-Object -First 1 |
} |
ForEach-Object {
$Basename = Split-Path -Path $_.Directory -Leaf
foreach ($Email in ($NamesFolders | Where-Object {$_.Folder -eq $Basename}))
{If (((Get-Date).Date - $_.LastWriteTime.Date).TotalDays -gt 7)
{
#Create initial objects
$smtpServer = "mysmtpserver"
$msg = new-object Net.Mail.MailMessage
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
#Email structure
$msg.From = "xxx@mydomain.com"
$msg.ReplyTo = "xxx@mydomain.com"
$msg.To.Add($Email.EmailAddress)
$msg.To.Add($Email.EmailAddress2)
$msg.To.Add($Email.EmailAddress3)
$msg.subject = "!!! Retard SYNCTOY !!! : $($_.Directory)"
$msg.body = $_ | Select @{Name='Répertoire Synctoy';Expression={$_.Directory -replace '.+Itinérants', ''}},`
@{Name='Dernière synchro';Expression={$_.LastWriteTime}},`
@{Name='Jours de retard';Expression={((Get-Date).Date - $_.LastWriteTime.Date).TotalDays}} | fl | Out-String
#Send email
$smtp.Send($msg)