Determining archive attributes of .pdf files

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.”

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

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

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

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.”

Where-Object has been part of PowerShell from day one. See TechNet Wiki

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.

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…

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

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 :slight_smile:

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