locked
Trying to grab file stats off remote machines in PowerShell RRS feed

  • Question

  • Hi, I'm trying to run this script locally on each machine in our domain and not from a list due to firewall restrictions. I'd like to call a simplified version of this powershell script from a batch job run through Altiris Deployment Solution (what this company uses). All it needs to do is go into a directory and check some .png and .gif file sizes and report back the name of the machine and the file size. I can get this to run from a list, but since these machines aren't reachable, I just want to run it over a batch script. Thanks

    # Read input file and process each machine
    Get-Content C:\Scripts\win7active.txt | ForEach {
        
        # Save the computer name for later use
        $computerName = $_

        # Check the directories for every user found on the machine
        Get-ChildItem -Path \\$computerName\c$\Users\*\AppData\Roaming\Microsoft\Signatures\*.* -include ('*.gif', '*.png') | ForEach {

            # Create a hashtable with information about each file and the machine it came from
            $props = @{
                ComputerName = $computerName
                File = $_.FullName
                Size = $_.Length
                Date = $_.CreationTime 
            }

            # Create an object based on the hashtable above
            # These will build up as the loop progresses, making exporting to CSV easy
            New-Object PsObject -Property $props

        }

    } | Sort ComputerName | \\dfs_source\dfsAppmediaSrc\Testing\Marc\logo.csv -Append
    # The line above sorts the output and then writes it to a CSV file



    • Edited by MarcGel Friday, May 23, 2014 7:00 PM
    Friday, May 23, 2014 6:51 PM

Answers

  • Your final script should look something like this:


    Get-ChildItem -Path c:\Users\*\AppData\Roaming\Microsoft\Signatures\* -include *.gif,*.png -Recurse | ForEach-Object {
      New-Object PSObject -Property @{
        ComputerName = $Env:COMPUTERNAME
        File = $_.FullName
        Size = $_.Length
        CreationTime = $_.CreationTime 
      } | select-object ComputerName,File,Size,CreationTime
    } | Export-Csv \\dfs_source\dfsAppmediaSrc\Testing\Marc\$Env:COMPUTERNAME.csv -NoTypeInformation
    

    In your output directory, you will have a series of CSV files, one for each computer. You can then combine them and create a single CSV, using code like this:


    get-childitem *.csv | foreach-object {
      import-csv $_
    } | export-csv All.csv -notypeinformation
    


    -- Bill Stewart [Bill_Stewart]


    • Edited by Bill_Stewart Friday, May 23, 2014 8:37 PM Forgot -Recurse
    • Marked as answer by MarcGel Friday, May 23, 2014 8:56 PM
    Friday, May 23, 2014 8:32 PM
  • Forgot about that. You would need to exclude that CSV from the Get-ChildItem, as in:


    get-childitem *.csv -exclude All.csv | foreach-object {
      import-csv $_
    } | export-csv All.csv -notypeinformation
    


    -- Bill Stewart [Bill_Stewart]

    • Marked as answer by MarcGel Friday, May 23, 2014 9:12 PM
    Friday, May 23, 2014 9:10 PM

All replies

  • To run this on the current computer only, you need to:

    1. Remove the "Get-Content C:\Scripts\win7active.txt | ForEach" loop, since you don't want to do that.

    2. Change "Get-ChildItem -Path \\$computerName\c$\Users\..." to "Get-ChildItem -Path c:\Users\..."

    3. You can get the current computer's name using "$Env:COMPUTERNAME".

    4. You will probably want to write this output somewhere, such as a file share.


    -- Bill Stewart [Bill_Stewart]

    Friday, May 23, 2014 7:00 PM
  • Thanks, where does the "$Env:COMPUTERNAME" go? Also, is there a variable to check which user is the current user and not every user who's ever logged into a machine?
    • Edited by MarcGel Friday, May 23, 2014 7:05 PM
    Friday, May 23, 2014 7:03 PM
  • Thanks, where does the "$Env:COMPUTERNAME" go?

    I'm not sure I understand your question. You would want to include it in your output, presumably.

    Also, is there a variable to check which user is the current user and not every user who's ever logged into a machine?

    Try "$Env:USERNAME".


    -- Bill Stewart [Bill_Stewart]

    Friday, May 23, 2014 7:07 PM
  • Sorry, I can't seem to get the syntax correct; 

       $Env:COMPUTERNAME = $_
        Get-ChildItem -Path c:\Users\$Env:USERNAME\AppData\Roaming\Microsoft\Signatures\*.* -include ('*.gif', '*.png') | ForEach {
            $props = @{
                ComputerName = $Env:COMPUTERNAME
                File = $_.FullName
                Size = $_.Length
                Date = $_.CreationTime 
            }
            New-Object PsObject -Property $props

        } | Sort ComputerName | Export-Csv \\dfs_source\dfsAppmediaSrc\Testing\Marc\logos.csv -NoTypeInformation


    Friday, May 23, 2014 7:15 PM
  • Remove the first line containing "$Env:COMPUTERNAME = $_".

    Next, change "Get-ChildItem -Path c:\Users\$Env:USERNAME\AppData\..." to just "Get-ChildItem -Path c:\Users\AppData\...". (Think about this a little bit.)

    You also don't need "| Sort ComputerName" since you are working with only the current computer.

    Finally I would recommend naming your CSV file after the computer name:

    "| export-csv \\dfs_source\dfsAppmediaSrc\Testing\Marc\$Env:COMPUTERNAME.csv"


    -- Bill Stewart [Bill_Stewart]


    Friday, May 23, 2014 7:23 PM
  • But ideally I'd like to not have hundreds of spreadsheets created, just one with the machine name, file, date, length columns in it. This seems to finish but then there's no data in the spreadsheet. 

        Get-ChildItem -Path c:\Users\*\AppData\Roaming\Microsoft\Signatures\*.* -include ('*.gif', '*.png') | ForEach {
            $props = @{
                $computername = $_
                File = $_.FullName
                Size = $_.Length
                Date = $_.CreationTime 
            }
            New-Object PsObject -Property $props

        } | Export-Csv \\dfs_source\dfsAppmediaSrc\Testing\Marc\logos.csv -Append

    Friday, May 23, 2014 7:30 PM
  • I recommend naming the files differently and collect the data from them later, because if two users log on at the same time, you will have contention to write to the file.

    If there's no output, then the get-childitem cmdlet returned no data.


    -- Bill Stewart [Bill_Stewart]

    Friday, May 23, 2014 7:42 PM
  • Ok, good point. Getting closer on this. 2 small problems. 1 with the $Env:COMPUTERNAME.csv , a spreadsheet is created but no name is assigned (.csv). 2.unless I put a username in the path c:\Users\mcg2\AppData\Roaming\Microsoft\Signatures\*.* it can't find the data. How can I adjust the -path statement to use $env:username or how to I use a wildcard that will work on all user profiles?

        Get-ChildItem -Path c:\Users\*\AppData\Roaming\Microsoft\Signatures\*.* -include ('*.gif', '*.png') | ForEach {
            $computername = $_
            $props = @{
                $computername = $_
                File = $_.FullName
                Size = $_.Length
                Date = $_.CreationTime 
            }
            New-Object PsObject -Property $props

        } | Export-Csv \\dfs_source\dfsAppmediaSrc\Testing\Marc\$Env:COMPUTERNAME.csv -Append


    • Edited by MarcGel Friday, May 23, 2014 7:54 PM
    Friday, May 23, 2014 7:52 PM
  • I think your get-childitem needs to look like this:


    Get-ChildItem -Path c:\Users\*\AppData\Roaming\Microsoft\Signatures\* -include *.gif,*.png -recurse


    -- Bill Stewart [Bill_Stewart]

    Friday, May 23, 2014 8:04 PM
  • Ok, cool. Last question, is the lack of name for the .csv because it is just a placeholder for when I run this against a bunch of machines and the spreadsheet will fill up with each machine and users path data? And then I just rename later? Or how does that work? Thanks Bill. 
    Friday, May 23, 2014 8:16 PM
  • Your final script should look something like this:


    Get-ChildItem -Path c:\Users\*\AppData\Roaming\Microsoft\Signatures\* -include *.gif,*.png -Recurse | ForEach-Object {
      New-Object PSObject -Property @{
        ComputerName = $Env:COMPUTERNAME
        File = $_.FullName
        Size = $_.Length
        CreationTime = $_.CreationTime 
      } | select-object ComputerName,File,Size,CreationTime
    } | Export-Csv \\dfs_source\dfsAppmediaSrc\Testing\Marc\$Env:COMPUTERNAME.csv -NoTypeInformation
    

    In your output directory, you will have a series of CSV files, one for each computer. You can then combine them and create a single CSV, using code like this:


    get-childitem *.csv | foreach-object {
      import-csv $_
    } | export-csv All.csv -notypeinformation
    


    -- Bill Stewart [Bill_Stewart]


    • Edited by Bill_Stewart Friday, May 23, 2014 8:37 PM Forgot -Recurse
    • Marked as answer by MarcGel Friday, May 23, 2014 8:56 PM
    Friday, May 23, 2014 8:32 PM
  • Question, I ran this against 2 test machines and it works great! It created 2 spread sheets with the names of the machine as the .csv. However, when I ran the second script to combine them, it looped till error. Also the All.csv was huge and had repeated file information so apparently it didn't know when to stop?

    import-csv : Access to the path is denied.
    At \\dfs_source\dfsAppmediaSrc\Testing\Marc\combineexcelsheets.ps1:2 char:3
    +   import-csv $_
    +   ~~~~~~~~~~~~~
        + CategoryInfo          : NotSpecified: (:) [Import-Csv], UnauthorizedAccessException
        + FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.PowerShell.Commands.ImportCsvCommand




    • Edited by MarcGel Friday, May 23, 2014 9:06 PM
    Friday, May 23, 2014 8:49 PM
  • Forgot about that. You would need to exclude that CSV from the Get-ChildItem, as in:


    get-childitem *.csv -exclude All.csv | foreach-object {
      import-csv $_
    } | export-csv All.csv -notypeinformation
    


    -- Bill Stewart [Bill_Stewart]

    • Marked as answer by MarcGel Friday, May 23, 2014 9:12 PM
    Friday, May 23, 2014 9:10 PM
  • Awesome! Thanks a bunch Bill!
    Friday, May 23, 2014 9:12 PM
  • NP, glad you have a working solution.

    -- Bill Stewart [Bill_Stewart]

    Friday, May 23, 2014 9:35 PM