locked
Get Files List, Send Report, Parallel RRS feed

  • Question

  • Good afternoon,

    I am trying to solve the problem and already so tired to look for a solution

    You need:
    1. Get a list of machines from OU
    2. Scan each drive for files
    3. Get the mail address of the user from AD to a remote computer
    4. Send scan results to the post office box of the user and administrator
    5. Run all this in a variety of flow-parallel

    Searching I found, Invoke-Parallel
    https://gallery.technet.microsoft.com/scriptcenter/Run-Parallel-Parallel-377fd430

    The script works fine if he is looking for files - create a report for a single computer

    When the script runs with the list, miracles begin. Come reports only one computer from the list (for the rest does not come), or do not come at any recipients. Also, if you use the file search as C:\* e scan result is duplicated in the report file. If you specify a UNC path \\servername\c$ log files fill the correct data.

    Here is what I got and what I have is not working:

    $OU = 'ou=test,dc=root,dc=local'
    $Throttle = 10
    (Get-ADComputer -Filter * -SearchBase $OU).Name | Out-File $env:TEMP\Servers.txt 
    $servers = Get-Content $env:TEMP\Servers.txt
    Invoke-Parallel -InputObject $servers -Throttle 10 -ScriptBlock {
    if($ping = Test-Connection -ComputerName $_ -BufferSize 16 -quiet -count 2) 
    {
    Try {
    Get-WMIObject Win32_LogicalDisk -filter "DriveType = 3" -ComputerName localhost | select DeviceID | %{(Get-ChildItem ($_.DeviceID + '\') -Include *.doc -Recurse -Force -ErrorAction Ignore).FullName} |  Out-File $env:TEMP\$_.txt
    $username=((gwmi win32_computersystem -computer $_).UserName -split '\\')[1]
    if($user=Get-AdUser $username -properties mail){
       $email=$user.mail
       Send-MailMessage -SmtpServer smtpserver.root.local -to admin@email.com  -Bcc ((Get-AdUser $email -properties mail).mail) -Body $_ -From sender@email.com -Subject $_ -Attachments $env:TEMP\$_.txt
    }
    else{Send-MailMessage -SmtpServer smtpserver.root.local -to admin@email.com -Body $_ -From sender@email.com -Subject $_ -Attachments $env:TEMP\$_.txt
    }
    }
    Catch {''}
    }
    }

    This one script works, but as soon as I put the variable in a copy of the recipient reports come just for one computer from the list (last on the list). If I do not specify a variable after the search report is generated, the recipient receives all the letters. 

    $OU = 'ou=test,dc=root,dc=local'
    $Throttle = 10
    (Get-ADComputer -Filter * -SearchBase $OU).Name | Out-File $env:TEMP\Servers.txt 
    $servers = Get-Content $env:TEMP\Servers.txt
    Invoke-Parallel -InputObject $servers -Throttle 10 -ScriptBlock {
    if($ping = Test-Connection -ComputerName $_ -BufferSize 16 -quiet -count 2) 
    {
    Try {
    (Get-ChildItem ('\\' + $_ + '\c$') -Include *.doc -Recurse -Force -ErrorAction Ignore).FullName} |  Out-File $env:TEMP\$_.txt
    Send-MailMessage -SmtpServer smtpserver.root.local -to admin@email.com  -Body $_ -From sender@email.com -Subject $_ -Attachments $env:TEMP\$_.txt
    }
    Catch {''}
    }

    Please help, I have no strength and expertise to cope this task :(



    Monday, May 25, 2015 1:16 PM

Answers

  • That is what I just showed you how to do.

    You do not pass in computers.  Workflow does that for you.  Start by learnignbasic PowerSHell then spend sometime learning how Workflow works. Learn how to format code so that it is readable.

    Here is an example of howto use remoting workflows:

    workflow Test-GetFiles {
        Get-ChildItem c:\*.doc -Recurse -Force
    }
    
    Test-GetFiles -PSComputerName pc1,pc2,pc3,pc4 | select fullname
    
    This runs a parallel workflow against each computer


    \_(ツ)_/

    Tuesday, May 26, 2015 10:26 AM
  • If you doo want too run it all locally then do this:

    workflow test-getfiles{
       Param($computers)
       foreach -parallel ($computer in $computers){
            Get-ChildItem \\$computer\c$\temp\*.txt -Recurse -Force
       }
    }
    test-getfiles pc1,pc2,pc3,pc4 |select fullname
    
    


    \_(ツ)_/

    Tuesday, May 26, 2015 10:33 AM

All replies

  • You would do better with answers and with understanding if you were to format your code so that it is readable.

    Your question is a bit muddled. Try asking one simple question with a small piece of code illustrating your issue.

    You need to say what "not working" means.  What are the errors?  Have you tried tracing?

    Your script cannot be run remotely because the modules required are noo available remotely.

    What is the pupose of connecting to a remote coomoputer and having it ping itself.

    I think you need to rethink what you want to do.  A workflow can make it faster but you need to use a workflow and not Invoke-Parallel or use invoke correctly.

    Finally you should post questions about how to use a custom repository script to the author here: https://gallery.technet.microsoft.com/scriptcenter/Run-Parallel-Parallel-377fd430/view/Discussions#content


    \_(ツ)_/


    • Edited by jrv Monday, May 25, 2015 3:09 PM
    Monday, May 25, 2015 3:04 PM
  • Suggestion:  Start by making your scriptblock work independently against more that just to local system.  You will see what I am referring to.

    \_(ツ)_/

    Monday, May 25, 2015 3:11 PM
  • Suggestion:  Start by making your scriptblock work independently against more that just to local system.  You will see what I am referring to.

    \_(ツ)_/

    I tried workflow - this method give excellent result.
    But I saw that a result of the first computer are added to the next.

    If search result of first computer in the list, found files (file01.doc or some else). In result of next computer they appear to. And so on other reports.

    Part of the script:


    $OU = 'ou=1,ou=test,dc=root,dc=local'
    $computers  = (Get-ADComputer -Filter * -SearchBase $OU).Name
    workflow Get-RemoteFiles {
      param([string[]]$Computers)
      foreach -parallel ($computer in $computers) {
    InlineScript {
    Get-WMIObject Win32_LogicalDisk -filter "DriveType = 3" -ComputerName $using:computer  | select DeviceID | %{(Get-ChildItem ($_.DeviceID + '\Program Files\*') -Include *.doc -Recurse -Force -ErrorAction SilentlyContinue).FullName} | out-file $env:TEMP\$using:computer.txt
    }
    }

    Monday, May 25, 2015 11:21 PM
  • Suggestion:  Start by making your scriptblock work independently against more that just to local system.  You will see what I am referring to.


    \_(ツ)_/

    I tried workflow - this method give excellent result.
    But I saw that a result of the first computer are added to the next.

    If search result of first computer in the list, found files (file01.doc or some else). In result of next computer they appear to. And so on other reports.

    Part of the script:


    $OU = 'ou=1,ou=test,dc=root,dc=local'
    $computers  = (Get-ADComputer -Filter * -SearchBase $OU).Name
    workflow Get-RemoteFiles {
      param([string[]]$Computers)
      foreach -parallel ($computer in $computers) {
    InlineScript {
    Get-WMIObject Win32_LogicalDisk -filter "DriveType = 3" -ComputerName $using:computer  | select DeviceID | %{(Get-ChildItem ($_.DeviceID + '\Program Files\*') -Include *.doc -Recurse -Force -ErrorAction SilentlyContinue).FullName} | out-file $env:TEMP\$using:computer.txt
    }
    }

    Works like this:

    (Get-ChildItem ('\\' + $using:computer + '\c$\Program Files\*') -Include *.doc -Recurse -Force -ErrorAction SilentlyContinue).FullName |  out-file $env:TEMP\$using:computer.txt

    only UNC, or do not use %

    and

    (Get-ChildItem ('\\' + $using:computer + '\' + ((Get-WMIObject Win32_LogicalDisk -filter "DriveType = 3" -ComputerName $using:computer).DeviceID -replace ":") + '$\Program Files\*') -Include *.doc -Recurse -Force -ErrorAction SilentlyContinue).FullName |  out-file $env:TEMP\$using:computer.txt

    Wwork only for last computer in list, othe reports clear


    Monday, May 25, 2015 11:52 PM
  • I thinkyou donot understand how workflow works and I cannot decode what you are posting.

    We do not add computers to workflow.  They are automatically added and used. That is what the variable $PSComputerName is all about.


    \_(ツ)_/


    • Edited by jrv Tuesday, May 26, 2015 12:51 AM
    Tuesday, May 26, 2015 12:49 AM
  • I thinkyou donot understand how workflow works and I cannot decode what you are posting.

    We do not add computers to workflow.  They are automatically added and used. That is what the variable $PSComputerName is all about.


    \_(ツ)_/


    How can I search file on all drivers on remote computer, make parallel search process for each remote computer? And get report for each remote computer.

    $computers  = Get-Content c:\temp\Servers.txt
    workflow Test-GetFiles {
      param(
        [string[]]$Computers
      )
      foreach -parallel ($computer in $computers) {
    (Get-ChildItem ('\\' + $using:computer + '\c$\*') -Include *.doc -Recurse -Force -ErrorAction Ignore).FullName |  Out-File $env:TEMP\$using:computer.txt
      }
     }

    Tuesday, May 26, 2015 10:02 AM
  • That is what I just showed you how to do.

    You do not pass in computers.  Workflow does that for you.  Start by learnignbasic PowerSHell then spend sometime learning how Workflow works. Learn how to format code so that it is readable.

    Here is an example of howto use remoting workflows:

    workflow Test-GetFiles {
        Get-ChildItem c:\*.doc -Recurse -Force
    }
    
    Test-GetFiles -PSComputerName pc1,pc2,pc3,pc4 | select fullname
    
    This runs a parallel workflow against each computer


    \_(ツ)_/

    Tuesday, May 26, 2015 10:26 AM
  • If you doo want too run it all locally then do this:

    workflow test-getfiles{
       Param($computers)
       foreach -parallel ($computer in $computers){
            Get-ChildItem \\$computer\c$\temp\*.txt -Recurse -Force
       }
    }
    test-getfiles pc1,pc2,pc3,pc4 |select fullname
    
    


    \_(ツ)_/

    Tuesday, May 26, 2015 10:33 AM
  • If you doo want too run it all locally then do this:

    workflow test-getfiles{
       Param($computers)
       foreach -parallel ($computer in $computers){
            Get-ChildItem \\$computer\c$\temp\*.txt -Recurse -Force
       }
    }
    test-getfiles pc1,pc2,pc3,pc4 |select fullname
    


    \_(ツ)_/

    Like this, how can I get all drives by this script :) C$ D$ E$ .. Z$

    script works fine if I use only \\$computer\c$

    Tuesday, May 26, 2015 11:13 AM