5

I am using PowerShell 5.0 and working on a script to find and list all the versions of log4net.dll under the current directory recursively.

Get-ChildItem log4net.dll -Recurse | % versioninfo | Export-Csv "C:\MyJunk\log4net.csv"

The above statement begins returning version information as expected but execution stops at the first folder I lack permission to access:

Get-ChildItem : The specified network name is no longer available.
At line:1 char:1
+ Get-ChildItem log4net.dll -Recurse | % versioninfo | Export-Csv "C:\M ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : ReadError: (J:\ArcPlan_OracleWallet\Production:String) [Get-ChildItem], IOException
+ FullyQualifiedErrorId : DirIOError,Microsoft.PowerShell.Commands.GetChildItemCommand

Get-ChildItem : Access is denied
At line:1 char:1
+ Get-ChildItem log4net.dll -Recurse | % versioninfo | Export-Csv "C:\M ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (:) [Get-ChildItem], UnauthorizedAccessException
+ FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.PowerShell.Commands.GetChildItemCommand

I am running Windows PowerShell ISE as Adminstrator. ExecutionPolicy is RemoteSigned and $ErrorActionPreference is Continue.

Ideally I would like the script to interrogate each folder's ACL and bypass all folders (and their contents) I lack permission to access. However another solution would one in which hard-coded folders are bypassed. Being a novice in PowerShell I focused on the later.

I have tried bypassing the first problem folder (by name) to see if I could get that working, but encounter the same exception and processing stops.

Get-ChildItem log4net.dll -Recurse | Where-Object { $_.FullName -notmatch '\\ArcPlan_OracleWallet\\?'} | export-csv 'C:\MyJunk\log4net.csv'

Thanks.

  • 2
    `Get-ChildItem -Recurse -ErrorAction SilentlyContinue`? – Ansgar Wiechers May 11 '17 at 19:53
  • @Ansgar. Thanks for the replay. I still get the Access is denied exception. – Steve Brueckman May 11 '17 at 20:20
  • `The specified network name is no longer available` is this error message incorrect or do you really have a network issue? Maybe this is why the script execution stops? – sodawillow May 11 '17 at 20:50
  • @sodawillow I don't believe so. Using the command prompt I can open to the "J:\ArcPlan_OracleWallet" folder and view its contents. When I attempt `cd production` I get the Access is denied. error. – Steve Brueckman May 12 '17 at 20:31
  • Have you tried `Get-ChildItem -Force`? – sodawillow May 12 '17 at 20:45
  • I believe the issue was that the `Get-ChildItem log4net.dll -Recurse` would fail before the `Where-Object` could filter out the unwanted directories. My solution is fugly. It's too long to post here so I'll add it as an answer below. – Steve Brueckman May 12 '17 at 23:23

2 Answers2

2

If you want to ignore the errors, use -ErrorAction SilentlyContinue.

There are other useful values to this parameter, as you can discover here and here.

Here is a nice question quite on-topic.

You can also fetch help about this with Get-Help about_CommonParameters.

(Hi and welcome, if you dig this answer, read this ^^).

Community
  • 1
  • 1
sodawillow
  • 12,497
  • 4
  • 34
  • 44
  • 1
    I use `-ErrorAction SilentlyContinue` fairly often, and have found the shorter alias `-ea 4` to be easier and faster to type. `-ea` is an alias for `-ErrorAction` and `4` because `SilentlyContinue` is the fourth item in the [ActionPreference](https://msdn.microsoft.com/en-us/library/system.management.automation.actionpreference(v=vs.85).aspx) enum. – TheMadTechnician May 11 '17 at 20:29
  • 1
    I think proper short version should be -ea 0 `PS H:\> 0..5 | % {write-Host $_ ([System.Management.Automation.ActionPreference]$_)}` `0 SilentlyContinue` `1 Stop` `2 Continue` `3 Inquire` `4 Ignore` `5 Suspend` – Igor May 11 '17 at 20:37
  • I've used `if (Test-Connection $host -Quiet -Count 2 -EA 0) { #host is online, go on }` many times before understanding the `-EA 0` bit : ) – sodawillow May 11 '17 at 20:39
  • @sodawillow. Thanks for the info. SilentlyContinue hides the errors, but the command still stops. – Steve Brueckman May 11 '17 at 20:44
  • @SteveBrueckman see my comment on your Q, let's go debug some more then :). – sodawillow May 11 '17 at 20:51
  • 1
    Just for the record, I also can see that the "-ErrorAction Continue -force" (Continue or SilentlyContinue) stops when a System.UnauthorizedAccessException is thrown. It can continue when a " FullyQualifiedErrorId : DirUnauthorizedAccessError" is encountered. – ohnezahn Nov 12 '21 at 09:12
2

I believe the issue was that the Get-ChildItem log4net.dll -Recurse would fail before the Where-Object could filter out the unwanted directories.

I want to avoid hard-coding directories, but here is my (klunky) solution so far.

## Version information will be retrieved for $fileName
$fileName = 'log4net.dll'

$ErrorActionPreference = 'Continue'

## Get directies - excluding those you lack permission to access
$directories = Get-ChildItem -Directory | 
    Where-Object {$_.FullName -inotmatch 'directory-1' -and 
                $_.FullName -inotmatch 'directory-2' -and
                $_.FullName -inotmatch 'directory-3'                    
} 

## Array to hold version information
$allFilesVersionInfo = @()

foreach ($directory in $directories) {

    ## Get all files recursively
    $files = Get-ChildItem -Path $directory.FullName $fileName -Recurse 

    foreach ($file in $files) {

        ## Get version information and add to array
        $fileVersionInfo = $file | % versioninfo 
        $allFilesVersionInfo += $fileVersionInfo
    }
}

# Write version information in arra to file
$exportFullPath = "C:\MyJunk\$($fileName)-version.csv"
$allFilesVersionInfo |  Export-Csv -Path $($exportFullPath)