Change file attributes based on specific dates

Hi EE... we are trying to change file attributes of bunch  of files to "-r" so our backup software can do its job.  The problem we are facing is that we want to change all files attributes to "-r" after 2017-1108.  Is there a way to use ATTRIB for this in combination of another apps or is there an apps that we can filter the files we want to change the attribute based on a range  of dates?

Thank you in advance.
rayluvsAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Jose Gabriel Ortega CastroCEOCommented:
Using Powershell will make the work easier:
Save the following code as Remove-ReadOnlyAttribute.ps1

[CmdletBinding()]
param(
    #it can be modified to match the path you want to start with. My Default was my test path
    [Parameter(Mandatory=$false,Position=0)]$path="D:\Lib\desktop\1",
    #default value is $false.
    [Parameter(Position=1,Mandatory=$false)][switch]$Recurse
)

#This is a constant so it won't be neccesary to be provided as a variable.
$date= new-object System.Datetime -argumentlist (2017,11,08,00,00,00)
#                                                yyyy mm dd hh mm ss

function Remove-ReadOnlyAttribute{
    [cmdletbinding()]
    param(
        [Parameter(Position=0,Mandatory=$true)]$Path,
        [Parameter(Position=0,Mandatory=$true)][DateTime]$DateTime,
        [Parameter(Position=1,Mandatory=$false)][switch]$Recurse
    )
    BEGIN{
        $exists=(Test-Path $Path)
    }
    PROCESS{
        if($exists){
            $Folders= [System.IO.Directory]::GetDirectories($Path)
            $Files = [System.IO.Directory]::GetFiles($Path)

            if($Files.Count -gt 0){
                foreach($file in $Files){
                    $fi = New-Object System.IO.fileinfo -ArgumentList $file
                    if($fi.LastWriteTime -gt $DateTime){
                        #Remove the read only attribute, like "attrib -r file"
                        Set-ItemProperty -Path $file -Name IsReadOnly -Value $false 
                    }
                }
            }

            #folders
            if($recurse){
                if($Folders.count -gt 0){
                    foreach($folder in $Folders){
                        Remove-ReadOnlyAttribute -Path $folder -DateTime $DateTime -recurse
                    }
                }
            }
        }
        else{
            Write-Host "The folder '$Path' does not exists, please select a valid path"
        }
    }
    END{}
}

Remove-ReadOnlyAttribute -Path $path -DateTime $date -Recurse:$Recurse




#get files recursively      where the Lastwritetime is older than $dateformat, foreach item set the readonly attribute to false
#Get-ChildItem -Recurse -Path $path -File -Name | where{ $_.LastWriteTime -gt $DateInformat} | %{ Set-ItemProperty $_ -Name IsReadOnly -Value $true}
#Get-ChildItem -Recurse -Path $path   | where{ $_.LastWriteTime -gt $DateInformat} | %{ Set-ItemProperty $_ -Name IsReadOnly -Value $false}

Open in new window


In a elevated powershell console run:
set-executionpolicy unrestricted
#Navegate to the file where it is   C:\users\user\Desktop
cd "C:\users\user\Desktop"
#use the script
.\Remove-ReadOnlyAttribute.ps1 -path "C:\This\Is\the\Path" -recurse



I'm comparing with:  if($fi.LastWriteTime -gt $DateTime)    but you have a bunch of options:  please check here: FileInfo Class https://msdn.microsoft.com/en-us/library/system.io.fileinfo(v=vs.110).aspx
1
Jackie ManIT ManagerCommented:
What backup software you are using?

I have not yet seen such a backup software which needs to change the attributes of the files to be backup.
0
Qlemo"Batchelor", Developer and EE Topic AdvisorCommented:
Jose, any reason for overcomplicating things and not used what you commented in the last two lines?

I agree to Jackie, never seen backup software only looking for read-only files ...
0
Cloud as a Security Delivery Platform for MSSPs

Every Managed Security Service Provider (MSSP) needs a platform to deliver effective and efficient security-as-a-service to their customers. Scale, elasticity and profitability are a few of the many features that a Cloud platform offers. View our on-demand webinar to learn more!

Jose Gabriel Ortega CastroCEOCommented:
Yeah, couldn't make it work with the last lines :/ I'm pretty sure you could go on that and make it work

Well I don't think is overcomplicating it's just a function and it calls itself recursively. But I know it can make in one or 2 lines. just couldn't make it work that way.
0
Joe Winograd, Fellow&MVEDeveloperCommented:
> I agree to Jackie, never seen backup software only looking for read-only files ...

He surely meant to say the "-a" attribute — the Archive bit — which is used by some backup software to know if a file has changed since the last time it was backed up (or is new). Regards, Joe
0
rayluvsAuthor Commented:
Jose,

- Made a mistake on my question, I  meant "+a"  (we want the BackupApps to backup the desired files).
- What do we change in the script?
- Don't understand what you mean after your line "In a elevated powershell console run:"

Jackie & Qlemo,

My bad, sorry about that guys. I meant I want to set files modified after 2017-1108 to "+a" (sets the archive file attribute)

jOE,

Correct, that is what I meant


Finally, we want you guys input on this script we found:
$Source = 'C:\Users\username\Documents\'
$BackupDate = [DateTime] "2017-11-08"
dir -recurse $Source |  ? { $_.Attributes -like '*Archive*' -and  $_.LastWriteTime -lt $BackupDate } | % {  $_.Attributes += 

Open in new window

0
Qlemo"Batchelor", Developer and EE Topic AdvisorCommented:
Makes much more sense now ;-).
The script is incomplete, but similar to what I'm working with.

Jose:
Get-ChildItem -recurse -file | ? { $_.LastWriteTime -gt $date } | Set-ItemProperty  -name IsReadOnly -value $false

Open in new window

but that only works that easily with the r/o attribute (as it is a specific property of [System.IO.FileInfo]. The archive bit needs more work:
$Archive = [IO.FileAttributes]::Archive
Get-ChildItem -recurse -file |
  ? { $_.LastWriteTime -gt $date -and $_.attributes -notcontains $Archive} |
  % { Set-ItemProperty $_ -name attributes -value ($_.attributes -bxor $Archive) -verbose }

Open in new window

The -verbose can be removed if you do not want to get feedback about the files touched.
1
rayluvsAuthor Commented:
Ran this in PS apps, got the following:

PS C:\Users\username\Documents)> C:\Users\username\Documents\zSetAttribute(b).ps1
File C:\Users\username\Documents\zSetAttribute(b).ps1 cannot be loaded because running scripts is disabled on this system. For more 
information, see about_Execution_Policies at https:/go.microsoft.com/fwlink/?LinkID=135170.
    + CategoryInfo          : SecurityError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : UnauthorizedAccess

Open in new window

0
Qlemo"Batchelor", Developer and EE Topic AdvisorCommented:
Run Set-ExecutionPolicy RemoteSigned once inside of the PowerShell session. It then allows to run local scripts not downloaded from Internet, which should be secure enough.
The original setting is thought to protect you from apps running PowerShell scripts without you knowing they do.
0
rayluvsAuthor Commented:
message:
zSetAttributeB.ps1 : The term 'zSetAttributeB.ps1' is not recognized as the name of a cmdlet, function, script file, or oper
or if a path was included, verify that the path is correct and try again.
At line:1 char:1
+ zSetAttributeB.ps1
+ ~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (zSetAttributeB.ps1:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

Open in new window


The batch file name is 'zSetAttributeB.ps1'

the lines within the file is:
$Archive = [IO.FileAttributes]::Archive
Get-ChildItem -recurse -file |  ? { $_.LastWriteTime -gt $date -and $_.attributes -notcontains $Archive} |   % { Set-ItemProperty $_ -name attributes -value ($_.attributes -bxor $Archive) -verbose }

Open in new window


- We open Powershell,
- ran Set-ExecutionPolicy RemoteSigned
- ren the file zSetAttributeB.ps1


also tried it in,
- open CMD
- Powershell.exe set-executionpolicy remotesigned -File zSetAttributeB.ps1

same message
0
David Johnson, CD, MVPOwnerCommented:
Powershell.exe set-executionpolicy remotesigned -File zSetAttributeB.ps1

Open in new window

change it to
Powershell.exe -executionpolicy bypass -File zSetAttributeB.ps1

Open in new window

0
Qlemo"Batchelor", Developer and EE Topic AdvisorCommented:
You need to provide the full or relative path (at least .\ for the current folder) when trying to run PS scripts. This again is a security measure to not allow to place malicious files somewhere earlier in your search path, named like a well-known script or command (imagine something like dir.ps1 to hijack dir usage).
0
rayluvsAuthor Commented:
Ok, just to make sure we are have it right:

This the PS file (zSetAttributeB.ps1) we have created wit EE help:
$Archive = [IO.FileAttributes]::Archive
Get-ChildItem -recurse -file |  ? { $_.LastWriteTime -gt $date -and $_.attributes -notcontains $Archive} |   % { Set-ItemProperty $_ -name attributes -value ($_.attributes -bxor $Archive) -verbose }

Open in new window


To tun it, we do the following:
1. open CMD
2. type and run Powershell.exe -executionpolicy bypass -File zSetAttributeB.ps1

We want the above script to do the following:
1. I want to change the archive bit "+a" to selected files.
2. The selected file are all files dated 11/8/2017 and after.
3. The path is current (where the script is run) and all sub-folder thereafter.

based on the above, our question is:
1. What is missing?
2. How do we correctly run this file?
0
Qlemo"Batchelor", Developer and EE Topic AdvisorCommented:
The current location is missing, for example. And the date to use. Best to store the script as follows somewhere unrelated to the location you want to change, say C:\Scripts\zSetAttributeB.ps1:
$date = [DateTime] '2017-11-08'
$root = 'c:\Temp\EE'

$Archive = [IO.FileAttributes]::Archive
Get-ChildItem $root -recurse -file |
  ? { $_.LastWriteTime -gt $date -and $_.attributes -notcontains $Archive} |
  % { Set-ItemProperty $_ -name attributes -value ($_.attributes -bxor $Archive) -verbose }

Open in new window

and then run it with
powershell -ExecutionPolicy Bypass -File C:\Scripts\zsetAttributeB.ps1

Open in new window

We could add providing the date and root folder as parameter when calling the script as an extension, but I guess that is going too far now.
0
rayluvsAuthor Commented:
It's giving a message:

The argument 'C:\Scripts\zsetAttributeB.ps1' to the -File parameter does not exist. Provide the path to an existing '.ps1' file as an argument to the -File parameter.

where is c:\Scripts comming from?
0
David Johnson, CD, MVPOwnerCommented:
Where did you save the script? you need to change c:\scripts to that location i.e.
c:\users\username\documents\wndowspowershell\scripts\zSetAttributeB.ps1

Open in new window

0
rayluvsAuthor Commented:
The script is located in the folder where I start execute the script
0
David Johnson, CD, MVPOwnerCommented:
then your batch file could be as simple as
powershell.exe -executionpolicy bypass .\zSetAttributeB.ps1
0
Qlemo"Batchelor", Developer and EE Topic AdvisorCommented:
Please reread my comment #a42390353. I wrote that the script is stored as 'C:\Scripts\zsetAttributeB.ps1', and the script itself contains a direct reference to the path the attributes should get changed on.
Using "current location" is prone to issues, so I do not recommend that.
0
rayluvsAuthor Commented:
That's what I thought; looked at it and there were no 'C:\Scripts\zsetAttributeB.ps1'; where would location be?

$date = [DateTime] '2017-11-08'
$root = 'c:\Temp\EE'

$Archive = [IO.FileAttributes]::Archive
Get-ChildItem $root -recurse -file |
? { $_.LastWriteTime -gt $date -and $_.attributes -notcontains $Archive} |
% { Set-ItemProperty $_ -name attributes -value ($_.attributes -bxor $Archive) -verbose }
0
Qlemo"Batchelor", Developer and EE Topic AdvisorCommented:
Directly above the code block ;-). But you did spot $root, which is the folder to change files in?
0
rayluvsAuthor Commented:
Excuse my ignorance and surely i am not seeing it, but you said "I wrote that the script is stored as 'C:\Scripts\zsetAttributeB.ps1'", please point that out so I can change it.
0
Qlemo"Batchelor", Developer and EE Topic AdvisorCommented:
You are thinking too much ;-) You store the script somewhere, e.g. C:\Scripts\zsetAttributeB.ps1
You then use the exact same path and name when calling
     powershell -ExecutionPolicy Bypass -File C:\Scripts\zsetAttributeB.ps1
0
rayluvsAuthor Commented:
Not thinking too much, just basing on what you say.

Ok, so your comment on 'C:\Scripts\zsetAttributeB.ps1', you really meant by "somewhere", is my "specific" folder, not literal 'C:\Scripts\zsetAttributeB.ps1'? right?

That said, ID: 42390132, I say  I used " $Source = 'C:\Users\username\Documents\' "- that is same folder that I have the PS script.

... maybe there is some other tool for changing attributes based on dates?
0
Jose Gabriel Ortega CastroCEOCommented:
Rayluvs

- Made a mistake on my question, I  meant "+a"  (we want the BackupApps to backup the desired files).
      Yeah, That mess up my answer. Thank you

- What do we change the script?
      Qlemo already did the solution. Btw Thank you Qlemo for the answer adding this to my personal knowledge to practice

- Don't understand what you mean by your line "In an elevated PowerShell console run:"
      I meant you to do this prior to run the script. https://youtu.be/tY29YFgxo1k

- About more tools, my answer would be no, right now PowerShell allows you to do this and much more. So I'd recommend learning it not resist it.
There should be a bunch of them, but there are no free tools that I've know to do this, I can create one for you using C# but that's a gig.
0
rayluvsAuthor Commented:
Understood.

Can you please point me to the solution where the script changes the archive bit to "+a" on all files dated 11/8/2017 and on?
0
Jose Gabriel Ortega CastroCEOCommented:
Will do tomorrow, basically, I'll combine my answer with Qlemo's
0
rayluvsAuthor Commented:
We are looking at PS, starting to learn it - just finish checking a comparison between CMD and PS and PS can even managing the registrywhen CMD don't.  You guys are right, this Tool is powerful.
0
Qlemo"Batchelor", Developer and EE Topic AdvisorCommented:
Please don't use that comment #a42390132  as reference. As said, it is incomplete. I want to add that it toggles the archive bit, and hence would not be reliable.
My suggested code in #a42390353 uses a similar variable $root containing the path with the files to change.
I told to use a different folder for the script itself because you will likely end up with several scripts for different tasks very soon.
0
rayluvsAuthor Commented:
My bad, I just re-read carefully your link ID 42390353 and I made an error: I left as  is yopur example of  "C:\Scripts\zsetAttributeB.ps1" instead of changing it to the real folder "c:\Users\username\Documents\", as said in my  entry ID: 42390132.

Will check it out, run it and get back to you.

(again so sorry for overlooking this)
0
rayluvsAuthor Commented:
Hi Guys!

Status:
Found a solution that does exactly what we need: Attribute Changer based on dates filters - works excellently!

Will proceed to close the question and award for all your help.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
rayluvsAuthor Commented:
(added the link if interested)
0
rayluvsAuthor Commented:
Set our entery as best since it solved the problem.

Again, thanx!!!!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Windows OS

From novice to tech pro — start learning today.