Author Posts

May 1, 2016 at 12:06 am

I am trying to build scripts that will allow me to identify files archive bit state, and change the state to either set or clear. I have looked at the "Scripting Guy" posts for Jan 26 and Jan 27, 2011. However, when I use "Get-itemproperty" on one of my files, the attribute returned is "directory" These are all .pdf files. If I look at the file property under Windows, it shows "ready for archiving" box checked. Can't build the script until I can see the archive state...
Background: I'm a newbie, but have taken both Powershell 3 courses by Jeffry and Jason in Microsoft Virtual Academy, and am partway through "Powershell 3 in a month of lunches."

May 1, 2016 at 5:38 am

https://blogs.technet.microsoft.com/heyscriptingguy/2011/01/26/use-a-powershell-cmdlet-to-work-with-file-attributes/

That post goes into detail.
Perhaps you can paate your code that you are getting unexpected results from.

May 1, 2016 at 11:05 am

$files = Get-ChildItem -Path '\\path\to\files' -Filter *.pdf
foreach ($file in $files){
    If ($file.Attributes -ne 'Archive'){$file.Attributes = 'Archive'}}

May 2, 2016 at 2:48 am

I can't say why one of your files would return the directory bit. But I have done a bit of testing, and to detect if archive bit is set or not on files, you can do something like this:

$Path      = 'C:\TEMP\TEST1'
$Filter    = '*.pdf'
$Attribute = [System.IO.FileAttributes]::Archive

# Get all files in $Path matching $Filter
Get-ChildItem -Path $Path -Filter $Filter -Recurse

# Get all files in $Path matching $Filter where $Attribute is set
Get-ChildItem -Path $Path -Filter $Filter -Recurse | Where-Object { $_.Attributes -band $Attribute }

# Get all files in $Path matching $Filter where $Attribute is NOT set
Get-ChildItem -Path $Path -Filter $Filter -Recurse | Where-Object { ($_.Attributes -band $Attribute) -ne $Attribute }

If you want to modify the bit, you can use this function I put together, to either Enable (Set), Disable (Remove) or Toggle the bit:

function Set-FileAttribute {
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
        [System.IO.FileInfo[]]
        $InputObject
        ,
        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [ValidateSet('Archive', 'Hidden', 'Normal', 'ReadOnly', 'System')]
        [System.String[]]
        $Attribute
        ,
        [Parameter(Mandatory = $true)]
        [ValidateSet('Disable','Enable','Toggle')]
        [System.String]
        $Action
        ,
        [Switch]
        $PassThru = $false
    )
    process {
        foreach ($Object in $InputObject) 
        {
            foreach ($Attrib in $Attribute) {
                $FileAttribute = [System.IO.FileAttributes]::$Attrib
                Switch ($Action) {
                    'Disable' { $ScriptBlock = { ($Object.Attributes -band (0xffffffff -bxor $FileAttribute)) } }
                    'Enable'  { $ScriptBlock = { ($Object.Attributes -bor $FileAttribute) } }
                    'Toggle'  { $ScriptBlock = { ($Object.Attributes -bxor $FileAttribute) } }
                }
                $Object.Attributes = &$ScriptBlock
            }
            if ($PassThru) {
                return $Object
            }
        }
    }
}


# Set attribute
Get-ChildItem -Path $Path -Filter $Filter | Set-FileAttribute -Attribute $Attribute -Action Enable -PassThru

# Set attribute
Get-ChildItem -Path $Path -Filter $Filter | Set-FileAttribute -Attribute $Attribute -Action Disable -PassThru

# Set attribute
Get-ChildItem -Path $Path -Filter $Filter | Set-FileAttribute -Attribute $Attribute -Action Toggle -PassThru

I hope you find it useful

May 3, 2016 at 1:56 am

Christian, I am working with the scripts. One question: When Ed Wilson "The Scripting Guy" wrote his article on toggling the archive bit in 2011, was this before the introduction of PowerShell ver 3.0 which introduced the "where-object" cmdlet? His method of determining the state of the archive bit in a file appears to be more complex than using "where-object."

May 3, 2016 at 10:24 am

Where-Object has been part of PowerShell from day one. See http://social.technet.microsoft.com/wiki/contents/articles/13769.powershell-1-0-cmdlets.aspx

The reason for the complexity in Eds post, may be because the posts where part of "Neglected Cmdlet Week" and thus aiming at describing the use of Get-ItemProperty and Set-ItemProperty.

May 3, 2016 at 1:00 pm

Christian: Ooops! Re-read help on "where-object" and noted that script blocks were introduced as another way to use the cmdlet. It was late. BTW, if I run
(Get-ItemProperty -path $path).attributes
for one of my target archive files, I get the result "Directory" but if I run
(Get-ChildItem -path $path).attributes
to the same file, I get "Archive, NotContentIndexed."
This file shows ready for archiving in Windows property. Any ideas?

Still playing with the scripts. I also spent time last night wondering why I couldn't find a help file for "Set-Fileattribute" until I realized it was a function you had ginned up. It just sounded Sooo official...

May 3, 2016 at 3:26 pm

Christian: Got the script to work. By removing the -filter parameter, I can also handle Word folders that need to be archived. I think this resolves the thread, as I now have a key set of tools.
However, this problem was just one part of my great Archive Project (to reduce three file cabinets and numerous 3-ring binders to a couple of DVD's)
If you would be interested in providing input or advice on future issues, is there a way to stay in touch? Or should I just begin new threads?
Peter Marsh

May 4, 2016 at 6:54 am

Good to hear you got it working.

As for the diff between attributes returned by Get-ItemProperty and Get-ChildItem, can't say really. I cannot reproduce that on my system. A file with the NotContentIndexed bit set, shows the same with both Cmdlets.

For future issues, just post them in new threads here, and I'm sure someone will help you out 🙂

May 10, 2016 at 11:13 pm

I am now going to incorporate these commands into script files...