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

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 {
        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
        [Parameter(Mandatory = $true)]
        [ValidateSet('Archive', 'Hidden', 'Normal', 'ReadOnly', 'System')]
        [Parameter(Mandatory = $true)]
        $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

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