Using an Advanced Function with Invoke-Command FilePath (HELP PLEASE)

Welcome Forums General PowerShell Q&A Using an Advanced Function with Invoke-Command FilePath (HELP PLEASE)

Viewing 14 reply threads
  • Author
    Posts
    • #228556
      Participant
      Topics: 2
      Replies: 8
      Points: 30
      Rank: Member

      So what I am trying to do is, run my advanced function that I finally finished and use it with invoke-command filepath so it can run on 1100 computers faster than one at a time.  What I did in my function is I have it set to output results, errors, and offline computers to their own csv files.  The function works great but how do I get it to create these files on my computer that is executing the invoke-command.  So it will bring back all of that info from the 1100 computers and save it into the 3 files on my computer.  I am only asking because I have spent a lot of time reading all of google and could not find a way to make this work.  I spent a lot of time learning correct formatting and the correct way to create an advanced function tool.  So I do not want to have something sloppy for the invoke-command part.  I have seen many functions written with invoke-command but they all seems to lose the blasting effect and are one computer at a time.  That’s not my goal here.  I like to blast it out to all at the same time.  Please can anyone help me with this.  I just want to run the filepath and function and create the output files on my computer instead of on each remote computer.  thank you all for your time and help.

       

       

      [/crayon]
    • #228601
      Participant
      Topics: 9
      Replies: 678
      Points: 2,683
      Helping Hand
      Rank: Community Hero

      Remember you don’t want your function doing too much. It collects computer info, it should not export to CSV. I recommend the following changes.

      • Remove any exporting or out-file’ing.
      • Make your function export an object, including any success or errors you plan to log. One object that you can manipulate down the pipeline.
      • Make write-verbose and other messages only write where appropriate. (It tells you something is exported regardless of if you chose to or not)

      Now if you intend to run this remotely on other computers, forget about message output in your function, no one is there watching it. You can have your script that calls the function show you feedback, as well as retrieve all the output objects. Invoke-command is going to return all the output to the calling session, then you can export and write as you wish. Being ran as a local script with no parameters is perfect to take advantage of invoke-commands ability to run all the jobs at the same time. Either of these will help you achieve your goal.

       

       

       

    • #228691
      Participant
      Topics: 2
      Replies: 8
      Points: 30
      Rank: Member

      Thank you Doug, for the info.  This is my first advanced function I have made.  I learned and wanted to make it look professional.  So thanks for the invoke-command examples.  For now my question is if I take out the offline computers, the errors and the results that are going to a file, how do i run this and get those results into files?  How do I make one object that gets the good info i want and the errors and offline.  I am not asking you to re-write my function.  Unless you know how to do it better.  What  was trying to do is make a template for local and remote functions and a template for invoke-command.  I just learned how to do pscustomobjects.  How would I get this same info out to files if it’s not built in to the function.  I understand what you are saying.  Make a function that does one thing.  Gets the info.   Then make something else that does something with the info.  I just don’t know what to do.  I am learning but I also want to do it the right way.  Thank you again.,  Dave

    • #228697
      Participant
      Topics: 9
      Replies: 678
      Points: 2,683
      Helping Hand
      Rank: Community Hero

      If you want to leave it as is then it seems you’ll have no choice but to gather the contents of all the logs you wrote locally and concatenate them into their respective, collective log.

    • #228706
      Participant
      Topics: 2
      Replies: 8
      Points: 30
      Rank: Member

      Thank you again how can I do it differently I guess I just don’t know how I’ve messed with it for three hours today I don’t know how how would you take out the writing to log files and how would you get that information if you could please share some examples thank you again for your time that’s why I love this community site because it’s created by some awesome power so guys and it has a lot of good people as part of the community and I hope to be answering these questions one day to. Thank you again how can I do it differently I guess I just don’t know how I’ve messed with it for three hours today I don’t know how how would you take out the writing to log files and how would you get that information if you could please share some examples thank you again for your time that’s why I love this community site because it’s created by some awesome power so guys and it has a Lotta good people as part of the community and I hope to be answering these questions one day to

    • #228721
      Participant
      Topics: 2
      Replies: 8
      Points: 30
      Rank: Member

      So I made a pc.txt file with 5 computers that are offline, 5 computers that I know have a remote wmi access error, and 5 computers that get good results.  So I took your examples and made this and it seems to work, it gets the 5 good computers and it gets 3 of the computers that have wmi errors so I guess they don’t throw errors when run locally.  It gets the 5 offline computers and 2 of the wmi error computers and puts those in the errorvariable results.  The $success variable I gave the invoke-command has the good results.  I didn’t even need a try and catch in the scriptblock.  I am still learning this but I didn’t know the errorvariable would get the scriptblock errors too, I just thought it got the computers the invoke-command could not run on so like the offline ones and ones with winrm errors.  But it seems to work.  Is it really this simple?  Am i getting it wrong?  Thanks for the help.

       

      [/crayon]
      • This reply was modified 6 months, 3 weeks ago by Dave N.
    • #228754
      Participant
      Topics: 9
      Replies: 678
      Points: 2,683
      Helping Hand
      Rank: Community Hero

      You are on the right track! I’d probably approach it like this. Return one object for every computer that is attempted. You collect all the info you want in this object then you just process the object in the end to log files or whatever.

      Create the object in the beginning with whatever info you have so far

       

      Then as you progress with your script you can add more properties, including your systeminfo object if successful.

       

      Once all are collected, process them.

    • #229009
      Participant
      Topics: 17
      Replies: 1872
      Points: 3,640
      Helping Hand
      Rank: Community Hero

      Get-WMIObject is deprecated, you should really be using Get-CimInstance. There are 7 WMI queries, which you are making 7 separate queries in 7 separate sessions. With CimSession, you are establishing a single session and then doing 7 queries. I’m with @KrzyDoug and don’t think having all of the exports should be in the function, especially as a switch without a path. Putting everything in an object, including status, provides a common schema that can be filtered to find specific results:

      Output:

    • #229031
      Participant
      Topics: 9
      Replies: 678
      Points: 2,683
      Helping Hand
      Rank: Community Hero

      @Rob Simmers  That is a beautiful script. I must copy and paste.

    • #229894
      Participant
      Topics: 2
      Replies: 8
      Points: 30
      Rank: Member

      Thank you for that advanced function re-write.  It looks great and was what I wanted to create.  Instead of outputting to 3 files it can all go to one file and then I can sort that CSV file.  I just did not know how to make the PSCustomObject collect all 3.  This was my first attempt at creating a correctly formatted advanced function like Don Jones says are tools in his training videos.  I just didn’t have the knowledge to make it the way you made this one.  I can now use this as an example for all advanced functions for collecting info good or bad in one csv file.

      Just wondering if you know how to use this with invoke-command filepath and have it write the results to a csv file that is locally on my computer.  Everything I do seems to create the csv file on the remote computer.

      thanks again both of you for the great info.  I love learning powershell.  It makes the work hours go by faster.

       

      • This reply was modified 6 months, 2 weeks ago by Dave N.
    • #229903
      Participant
      Topics: 17
      Replies: 1872
      Points: 3,640
      Helping Hand
      Rank: Community Hero

      Glad you’re having fun with Powershell, it can do a lot of cool things. Invoke-Command is invoking the command on the remote computer. As Doug and I were trying to explain, GET functions return a PsObject. They do not typically export in the function. Recommend you look at other Powershell examples in Invoke-Command help and how other commands work like Get-Service or Get-Process as a basic examples:

    • #229906
      Participant
      Topics: 2
      Replies: 8
      Points: 30
      Rank: Member

      I guess I don’t know how error handling works with invoke-command then.  I want to catch the same info, good results, errors, and offline computers.  Will the variable for the invoke-command catch all of that in the variable?  If so then that seems like an easy solution.  I can then separate it and export it.

    • #229909
      Participant
      Topics: 17
      Replies: 1872
      Points: 3,640
      Helping Hand
      Rank: Community Hero

      When you are using Get-CimInstance, you are connecting to the remote system with WSMan or DCOM to gather information. There is no need for Invoke-Command. Provide the function with a list of computers and it will create a session with the remote computers and collect the information and return it.

    • #229912
      Participant
      Topics: 2
      Replies: 8
      Points: 30
      Rank: Member

      I know but I have 1100 computer desktops to get info from.  One at a time takes hours.  But blasting it out to all of them takes 5 minutes.  Do you know of a good way to still collect all of that same info?  Thanks again.

    • #230083
      Participant
      Topics: 17
      Replies: 1872
      Points: 3,640
      Helping Hand
      Rank: Community Hero

      Yes, 5 minutes isn’t a long time, but there are ways to expedite things. Look at Jobs, which would allow you to split the computers into jobs, like 225 computers for each job and run in parallel, but the you would take the job results and combine them to have a single result:

      Parallel Processing with jobs in PowerShell

      The second option is using workflows to execute in parallel, this would be processing in a foreach loop:

      https://docs.microsoft.com/en-us/powershell/module/psworkflow/about/about_foreach-parallel?view=powershell-5.1

Viewing 14 reply threads
  • The topic ‘Using an Advanced Function with Invoke-Command FilePath (HELP PLEASE)’ is closed to new replies.