Powershell network drive Get-ChildItem issues

This topic contains 15 replies, has 6 voices, and was last updated by Profile photo of Dave Wyatt Dave Wyatt 2 years, 4 months ago.

  • Author
    Posts
  • #16872
    Profile photo of Adam Hudson
    Adam Hudson
    Participant

    Essentially I'm trying to use PowerShell to find files with certain file extensions on a network drive created on or after June 1st of this year. I thought I could do that with the following statement:

    Get-ChildItem NETWORKPATH\*.* -recurse -include *.xlsx | Where-Object { $_.CreationTime -ge "06/01/2014" }

    I run into 2 problems:

    1) The command only returns files from the root and one folder on the network drive, there's over 100 folders on this network drive
    2) The command returns 3 out of the 5 files created after 6/1/14 and one created well before my creation time date.

    I have access to all of the folders on the network drive. When I run Windows 7 search it finds all of the files. It doesn't matter if I run Powershell as administrator or not. It doesn't matter if I run it from my machine (Windows 7) or from one of our 2008 servers. The network drive I'm trying to search through is on a 2003 file server. What am I doing wrong?

    Any help is appreciated.

  • #16879
    Profile photo of Alexander Johansson
    Alexander Johansson
    Participant

    Do you get [b]all[/b] of the files if you execute the following code:

    Get-ChildItem -Path NETWORKPATH -Recurse -Force

    Or do you still only get some of the files?

  • #16880
    Profile photo of Mathieu Buisson
    Mathieu Buisson
    Participant

    First, I would remove "\*.*" at the end of NETWORKPATH.

    Second, are sure you have access to all the shares and all the subfolders in \\NETWORKPATH\ ?

    Also, if you pipe the first part of your command to Get-Member, you will see that the property CreationTime should be a DateTime object :

    Get-ChildItem NETWORKPATH -recurse -include *.xlsx | Get-Member -Name CreationTime
    
       TypeName: System.IO.FileInfo
    
    Name         MemberType Definition
    
    CreationTime Property   System.DateTime CreationTime {get;set;} 

    To make sure that your date is considered as a DateTime object, instead of a string, you can do this :

     Get-ChildItem NETWORKPATH -recurse -include *.xlsx | Where-Object { $_.CreationTime -ge ("06/01/2014" -as [DateTime] ) } 

    One word of caution : ("06/01/2014" -as [DateTime] ) can be interpreted differently , depending on your $PSCulture.
    For me, it was interpreted as 6th of January , not 1st of June, because my $PSCulture is English Ireland :

     $date2 = ("06/01/2014" -as [DateTime])
    $date2
    
    06 January 2014 00:00:00
    
    
    $PSCulture
    en-IE 

    If you don't like this behaviour, you can do it another way :

     [DateTime]$date3 = "06/01/2014"
    $date3
    
    01 June 2014 00:00:00 
  • #16905
    Profile photo of Mike F Robbins
    Mike F Robbins
    Participant

    Does the Windows 2003 file server have PowerShell installed? I'm sure you can make this work the way you're trying, but it's going to be inefficient. How inefficient depends on how many xlsx files reside in that location because the command will retrieve a list of all the xlsx files and perform the filtering on the local computer. The better option would be to install PowerShell version 2 on the Windows 2003 file server, enable PowerShell remoting and take advantage of PowerShell remoting by placing the Get-ChildItem command inside of the script block of Invoke-Command. That way all of the filtering is done at the source machine and you'll only pull the results across the network.

    Invoke-Command -ComputerName FileServerName {
        Get-ChildItem -Path LOCALPATH\*.xlsx -Recurse |
        Where-Object {$_.CreationTime -ge '06/01/2014'}
    }
    
  • #16915
    Profile photo of Adam Hudson
    Adam Hudson
    Participant

    @Alexander the -force option doesn't change the results

    @Mathieu removing *.* causes the whole command to return nothing. Additionally, I've run this command as an admin and not as an admin under my own account and under a network admin account with no difference in result. I know my account can at least access all the folders (certainly more than just the root and one random subfolder) and the network admin account can access anything on the network. That being said, issue #2 is a non-issue now since I found out some network files will have a creation date newer than their modified date if they've been copied from another location.

    @mike I can certainly try to install PowerShell on my 2003 server, but it will be a major inconvenience if that requires a restart. Additionally, do you think running it locally will return more results? My problem right now isn't that it takes a long time to run the command, it's that it only returns results for the root of the folder and one folder out of at least 100.

  • #16917
    Profile photo of Mike F Robbins
    Mike F Robbins
    Participant

    Try this:

    Get-ChildItem -Path NETWORKPATH\*.xlsx -Recurse |
    Where-Object {$_.CreationTime -ge '06/01/2014'}
    
  • #16923
    Profile photo of Adam Hudson
    Adam Hudson
    Participant

    @mike, this gives me the same result whether I put in the -Recurse option or not. It only shows me the xlsx files in the root that match the creationtime parameters

  • #16924
    Profile photo of Robert Hahn
    Robert Hahn
    Participant

    gci -path PATH -recurse | where {$_.extension -match "xlsx"}
    OR
    gci PATH\*\*.xlsx -recurse

    This is what you are missing. If you define the file extension in the get-child item it is only displaying results from within that container regardless if you put recurse. You need to through in a wildcard for possible subfolders as well.

  • #16925
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    I assume that you're using PowerShell 2.0. The behavior of Get-ChildItem is quite different on current versions. What worked for me in testing (on PowerShell 2.0) was to remove the \*.* portion of the path from your original command:

    Get-ChildItem NETWORKPATH -Recurse -Include *.xlsx | Where-Object { $_.CreationTime -ge "06/01/2014" }
    
  • #16926
    Profile photo of Robert Hahn
    Robert Hahn
    Participant

    Agreed. I was way off. Dave's text returns the correct contents of both the named directory as well as the subdirectories.

  • #16927
    Profile photo of Adam Hudson
    Adam Hudson
    Participant

    gci -path PATH -recurse | where {$_.extension -match "xlsx"} was the silver bullet to all of this. Thanks for everyone's help, double thanks to Robert for the answer. As this script has already been running for an hour I'm going to file Mike's lead and try to install Powershell on the actual file server.

  • #16977
    Profile photo of Adam Hudson
    Adam Hudson
    Participant

    Not sure if I need to start a new topic but I took Mike's advice to invoke the code remotely, now I'm having an issue with multiple -and -or statements.

    [i]PS H:\> Invoke-Command -computername SERVERNAME { Get-ChildItem -path E:\dfsroots\datastore2\public} | Where-Object {{ $_.e
    xtension-match "xls" -or $_.extension-match "xlk" } -and { $_.creationtime -ge "06/01/2014"}}[/i]

    Above is my code example. What I'm trying to do is remotely run this powershell code on my file server and have it return all xls and xlk files with a creation date on or later than 6/1/2014. When I run this code it starts spitting out all of the folders in that remote location. If I only compare two things like so:

    [i] PS H:\> Invoke-Command -computername SERVERNAME { Get-ChildItem -path E:\dfsroots\datastore2\public} | Where-Object { $_.extension-match "xls" -and $_.creationtime -ge "06/01/2014"}[/i]

    Only the xls files created on or after that date display. What's going on here? Do I need to use something other than nest -and -or statements? Any help is appreciated.

  • #16978
    Profile photo of Adam Hudson
    Adam Hudson
    Participant

    I'll note that breaking the "where" statements up didn't work either. I would run a command like:

    PS H:\> Invoke-Command -computername SERVERNAME { Get-ChildItem -path E:\dfsroots\datastore2\public} | Where-Object { $_.extension-match "xls" -or $_.extension-match "xlk" } | where-object { $_.creationtime -ge "06/01/2014"}

    And I'd get xlsx values returned which definitely not what I wanted.

  • #16980
    Profile photo of Adam Hudson
    Adam Hudson
    Participant

    Using parenthesis didn't work either, see the example below:

    PS H:\> Invoke-Command -computername owlnas2 { Get-ChildItem -path E:\dfsroots\datastore2\public} | Where-Object {( $_.extension-match "xls" -or $_.extension-match "xlk") -and $_.creationtime -ge "06/01/2014"}
  • #16982
    Profile photo of Adam Hudson
    Adam Hudson
    Participant

    Clarification, using parenthesis gave me the same result as splitting up my "where" statements. I'm searching for xls and xlk files and getting xlsx files in my results.

  • #16984
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    You're using a -match operator, which takes a regular expression. Any string which contains "xls" will return true when you say $someString -match 'xls'. There are a few ways you could change this code to work the way you like, mainly depending on your personal preference, performance requirements, and how you think it might change in the future.

    
    # Using an array of acceptable extensions.  Don't forget the period; it's part of the extension, as far as .NET is concerned.
    # Still using Where-Object (which may not perform as well)
    
    $extensionsToMatch = '.xls', '.xlsk'
    Get-ChildItem -Recurse | Where-Object { $extensionsToMatch -contains $_.Extension }
    
    # Using an array again, but this time passed to the -Include parameter of Get-ChildItem.  Should perform better than Where-Object.
    # This time, we need to add a * wildcard before the extensions in the array
    $extensionsToMatch = '*.xls', '*.xlsk'
    
    Get-ChildItem -Recurse -Include $extensionsToMatch
    
    

You must be logged in to reply to this topic.