none
How to simplify complex PowerShell if statemant?

    Question

  • Good morning,

    please any idea how to simplify following complex PowerShell if statemant?

    if ($child1 |

    Where-Object {$_.operatingsystem -notlike "Windows RT*"} |

    Where-Object {$_.operatingsystem -notlike "Microsoft Office Suite and Other Software"} |

    Where-Object {$_.operatingsystem -notlike "Antimalware Software"} |

    Where-Object {$_.operatingsystem -notlike "*for Mac*"} |

    Where-Object {$_.operatingsystem -notlike "Office Software"} |

    Where-Object {$_.operatingsystem -notlike "Software"} |

    Where-Object {$_.operatingsystem -notlike "Affected Software"} |

    Where-Object {$_.operatingsystem -notlike "File information"} |

    Where-Object {$_.operatingsystem -notlike "SHA1/SHA2 hashes"} |

    Where-Object {$_.operatingsystem -notlike "Known issues"} |

    Where-Object {$_.operatingsystem -notlike "Operating System"} |

    Where-Object {$_.operatingsystem -notlike "*Server*"} |

    Where-Object {$_.operatingsystem -notlike "*Vista x64*" } |

    Where-Object {$_.operatingsystem -notlike "*XP Professional x64*" } |

    Where-Object {$_.operatingsystem -notlike "Microsoft Office Software" }

    )

    {$Parent += $Child1 }

    Thank you :)



    • Edited by Ja Som Tuesday, January 07, 2014 7:31 PM
    Tuesday, January 07, 2014 7:15 PM

Answers

  • Since when is an operating system called "Software"?  We have no idea what you are doing and the run-on is unnecessary.

    Why can't you write it using code and a coolection of things to check instead of a brute force linear list of things?  It shows you have not used PowerShell or any codingin the past.

    Whenever anything becomes messy and cumbersome in computing it is a big clue that you are missing very important bits of information. While the structure may look useful it is going to be very slow and prone to failure. Also not understanding the criticism shows me that you will have more difficulties moving forward.

    Your initial question sounded like someone gave you this and you did not know anything about PowerShell.  If you wrote it then I wonder how you didn't come to format it in a readable way.

    I recommend spending a bit of time going through the training materials on this site.  They will help you to avoid "spaghetti" code like this in the future.

    By the way.  "Spaghetti code" is a technically used term that describes what you have done.  Look it up. https://www.google.com/#newwindow=1&q=spaghetti+code


    ¯\_(ツ)_/¯

    • Marked as answer by Ja Som Tuesday, January 07, 2014 8:29 PM
    Tuesday, January 07, 2014 7:56 PM

  • Yes I`m sure... <!DOCTYPE html> <html> <head> <meta charset="utf-8" />

    Actually the PowerShell V3 and later can now parse the DOCTYPE so it should load as XML.

    This loads as XML:

    [xml]'<!DOCTYPE html> <html> <head>  <meta charset="utf-8" /></head></html>'


    ¯\_(ツ)_/¯

    • Marked as answer by Ja Som Tuesday, January 07, 2014 9:34 PM
    Tuesday, January 07, 2014 9:28 PM

All replies

  • Start by formatting it so that it is readable.  It is just a mashup of nonsense as posted.


    ¯\_(ツ)_/¯

    Tuesday, January 07, 2014 7:27 PM
  • At minimum you could press enter after each of the pipes (|) and make it better suited to read... Perhaps you should move away from what you do not want in the operatingSystem attribute and focus on what you do want, and then use the -like logical operator.

    Tuesday, January 07, 2014 7:29 PM
  • Here:

    $child1 | 
           Where-Object{$_.operatingsystem -notlike "Windows RT*"} | 
           Where-Object{$_.operatingsystem -notlike "Microsoft Office Suite and Other Software"} | 
           Where-Object {$_.operatingsystem -notlike "Antimalware Software"} | 
           Where-Object {$_.operatingsystem -notlike "*for Mac*"} | 
           Where-Object {$_.operatingsystem -notlike "Office Software"} | 
           Where-Object {$_.operatingsystem -notlike "Software"} | 
           Where-Object {$_.operatingsystem -notlike "Affected Software"} | 
           Where-Object {$_.operatingsystem -notlike "File information"} | 
           Where-Object {$_.operatingsystem -notlike "SHA1/SHA2 hashes"} | 
           Where-Object {$_.operatingsystem -notlike "Known issues"} | 
           Where-Object {$_.operatingsystem -notlike "Operating System"} | 
           Where-Object {$_.operatingsystem -notlike "*Server*"} | 
           Where-Object {$_.operatingsystem -notlike "*Vista x64*" } | 
           Where-Object {$_.operatingsystem -notlike "*XP Professional x64*" } | 
           Where-Object {$_.operatingsystem -notlike "Microsoft Office Software" }
    

    It still won't work because it is just a bunch of mismatched nonsense.  Most lines are meaningless and many will not work as expected.


    ¯\_(ツ)_/¯

    Tuesday, January 07, 2014 7:33 PM
  • Here:

    $child1 | 
           Where-Object{$_.operatingsystem -notlike "Windows RT*"} | 
           Where-Object{$_.operatingsystem -notlike "Microsoft Office Suite and Other Software"} | 
           Where-Object {$_.operatingsystem -notlike "Antimalware Software"} | 
           Where-Object {$_.operatingsystem -notlike "*for Mac*"} | 
           Where-Object {$_.operatingsystem -notlike "Office Software"} | 
           Where-Object {$_.operatingsystem -notlike "Software"} | 
           Where-Object {$_.operatingsystem -notlike "Affected Software"} | 
           Where-Object {$_.operatingsystem -notlike "File information"} | 
           Where-Object {$_.operatingsystem -notlike "SHA1/SHA2 hashes"} | 
           Where-Object {$_.operatingsystem -notlike "Known issues"} | 
           Where-Object {$_.operatingsystem -notlike "Operating System"} | 
           Where-Object {$_.operatingsystem -notlike "*Server*"} | 
           Where-Object {$_.operatingsystem -notlike "*Vista x64*" } | 
           Where-Object {$_.operatingsystem -notlike "*XP Professional x64*" } | 
           Where-Object {$_.operatingsystem -notlike "Microsoft Office Software" }

    It still won't work because it is just a bunch of mismatched nonsense.  Most lines are meaningless and many will not work as expected.


    ¯\_(ツ)_/¯


    Thank you for your opinion, this is PS not bunch of mismatched nonsense and it is working, just want to simplify it ;)
    Tuesday, January 07, 2014 7:46 PM
  • Since when is an operating system called "Software"?  We have no idea what you are doing and the run-on is unnecessary.

    Why can't you write it using code and a coolection of things to check instead of a brute force linear list of things?  It shows you have not used PowerShell or any codingin the past.

    Whenever anything becomes messy and cumbersome in computing it is a big clue that you are missing very important bits of information. While the structure may look useful it is going to be very slow and prone to failure. Also not understanding the criticism shows me that you will have more difficulties moving forward.

    Your initial question sounded like someone gave you this and you did not know anything about PowerShell.  If you wrote it then I wonder how you didn't come to format it in a readable way.

    I recommend spending a bit of time going through the training materials on this site.  They will help you to avoid "spaghetti" code like this in the future.

    By the way.  "Spaghetti code" is a technically used term that describes what you have done.  Look it up. https://www.google.com/#newwindow=1&q=spaghetti+code


    ¯\_(ツ)_/¯

    • Marked as answer by Ja Som Tuesday, January 07, 2014 8:29 PM
    Tuesday, January 07, 2014 7:56 PM
  • if( $list -contains $_.operatingsystem )

    By using  single statement you can do all test in one shot.


    ¯\_(ツ)_/¯

    Tuesday, January 07, 2014 8:00 PM
  • Like this:
    PS C:\scripts> $list='john','george','paul','susan'
    PS C:\scripts> if($list -contains 'george'){'found'}else{'not found'}
    found
    PS C:\scripts> if($list -contains 'scot'){'found'}else{'not found'}
    not found


    ¯\_(ツ)_/¯

    Tuesday, January 07, 2014 8:02 PM
  • Store your "not like" words in a text file, read them in, and check them. I am using a variable called $InVar in place of what you would use for $child1.

    Text file:
    dog
    cat
    frog

    $Matches = Get-Content -Path 'C:\NotLikeWords.txt'
    $InVar = 'cat'
    
    If ($Matches -like $InVar) {
        Write-Output "It's in there"
    } Else {
        Write-Output "It's NOT in there"
    }


    Tuesday, January 07, 2014 8:09 PM
  • Some of the problems are that "like" only matches wildcards.

    If we want a word anywhere in a string it is best to use -match.  If we want exact we use -eq or -ne.  We can also use -notcontains.

    To match phrases or groups we want to use -match and -notmatch or -contains or -notcontains.

    Using this method we can load a list from a file or type it into an array.  The list can be complex phrases.

    Other things that can beiused are full regex expressions from a file that work with -match/-notmatch.

    The first thing to do is to state the logic simply as a list driven test.

    Much of this only takes a little experience.  One you grasp how code and software work then you can do very powerful things very easily.


    ¯\_(ツ)_/¯

    Tuesday, January 07, 2014 8:14 PM
  • In case I did not make it explicit enough.  "contains" can match an item against and array, a list, a hash or many other types of collections.  It matches based on item type. "like" and "match only match a single item and  "like" is used with wild cards and is very limited.


    ¯\_(ツ)_/¯

    Tuesday, January 07, 2014 8:17 PM
  • Sorry for being confusing...

    $Child1 is object with 5 different proprtyes, one of these is OperatingSystem and I need to parse $Child1 by property OperatingSystem and add matching object to $Parent hash table with all it`s properties.

    All of your responses help me realize piece off puzzle so thank you everybody and here is my solution based on your replays :)

    switch -wildcard ($child1.OperatingSystem)
        {
            "Windows XP Service Pack 3" {$Parent += $Child1}
            "Windows Vista Service Pack 2" {$Parent += $Child1}
            "Windows 7*" {$Parent += $Child1}
            "Windows 8*" {$Parent += $Child1}
        }

    For more detailed explanation see http.--technet.microsoft.com/en-us/library/ff730937.aspx

    Thank you and keep scripting


    • Edited by Ja Som Tuesday, January 07, 2014 9:32 PM
    Tuesday, January 07, 2014 8:24 PM
  • Well that won't work either as you are doing an exact match and a wildcard won't work.

    What are the "Child" objects.  Are the AD objects?  If so there is a much easier way to do this.  If they are WMI objects there is also aneasier way.

    If you actually explin what you are trying to do we can show you how to do it, Guessing is not going to get you there.


    ¯\_(ツ)_/¯

    Tuesday, January 07, 2014 8:37 PM
  • Also your use of the switch statement is a bit pointless as it does the same thing over and over.

    $parent+=$list -contains $child.operatingSystem

    That is all you need to do.


    ¯\_(ツ)_/¯

    Tuesday, January 07, 2014 8:42 PM
  • parsing HTML, getting tables and selecting required cells to assemble xlsx table with applicable information. To be more specific to assemble that excel table I have to wisit 1st url get few peaces and follow the link leading from 1st page to second again get some pieces of info for report and follow the 2nd link to get rest of info I need from 3rd site... long story short I`m parising cascaded web site :)
    • Edited by Ja Som Tuesday, January 07, 2014 8:46 PM
    Tuesday, January 07, 2014 8:45 PM
  • If it is XHTML you can parse it with XML.  If it is a table you can import it directly into Excel and dump it as CSV and parse it as data.

    In all cases you want to use collections and lists to match or exclude items.  It is very easy to set up and you just need to manage the lists.


    ¯\_(ツ)_/¯

    Tuesday, January 07, 2014 8:51 PM
  • Also your use of the switch statement is a bit pointless as it does the same thing over and over.

    $parent+=$list -contains $child.operatingSystem

    That is all you need to do.


    ¯\_(ツ)_/¯


    I`m not sure as I have +- 1000 $Child1 objects where OS property can be one of 50 different entries. so I have to filter and use only object with corresponding OS property and do it for each object $Child1
    Tuesday, January 07, 2014 8:51 PM
  • If it is XHTML you can parse it with XML.  If it is a table you can import it directly into Excel and dump it as CSV and parse it as data.

    In all cases you want to use collections and lists to match or exclude items.  It is very easy to set up and you just need to manage the lists.


    ¯\_(ツ)_/¯


    unfortunately it is pure HTML :( no XML or XHTML
    Tuesday, January 07, 2014 8:53 PM

  • I`m not sure as I have +- 1000 $Child1 objects where OS property can be one of 50 different entries. so I have to filter and use only object with corresponding OS property and do it for each object $Child1

    Doesn't matter. Place all of the items in a file one per line and load it into $list.

    You can enumerate the objects in a ForEach-Object block.  This is PowerShell.  If you spen a bit of time learning howit is designed you will find all of these complex seeming tasks are actually very basic.


    ¯\_(ツ)_/¯

    Tuesday, January 07, 2014 8:56 PM
  • If it is XHTML you can parse it with XML.  If it is a table you can import it directly into Excel and dump it as CSV and parse it as data.

    In all cases you want to use collections and lists to match or exclude items.  It is very easy to set up and you just need to manage the lists.


    ¯\_(ツ)_/¯


    unfortunately it is pure HTML :( no XML or XHTML

    Are you sure?  What does the DOCTYPE look like?  What is defined in the <html... tag?


    ¯\_(ツ)_/¯

    Tuesday, January 07, 2014 8:58 PM
  • If it is XHTML you can parse it with XML.  If it is a table you can import it directly into Excel and dump it as CSV and parse it as data.

    In all cases you want to use collections and lists to match or exclude items.  It is very easy to set up and you just need to manage the lists.


    ¯\_(ツ)_/¯


    unfortunately it is pure HTML :( no XML or XHTML

    Are you sure?  What does the DOCTYPE look like?  What is defined in the <html... tag?


    ¯\_(ツ)_/¯


    Yes I`m sure... <!DOCTYPE html> <html> <head> <meta charset="utf-8" />
    Tuesday, January 07, 2014 9:10 PM
  • Looks like HTML5 to me.  html5 is XML compliant.  Strip the doctype and it should load as XML.  The current XML parser does not know how to process a DOCTYPE statement.


    ¯\_(ツ)_/¯

    Tuesday, January 07, 2014 9:26 PM

  • Yes I`m sure... <!DOCTYPE html> <html> <head> <meta charset="utf-8" />

    Actually the PowerShell V3 and later can now parse the DOCTYPE so it should load as XML.

    This loads as XML:

    [xml]'<!DOCTYPE html> <html> <head>  <meta charset="utf-8" /></head></html>'


    ¯\_(ツ)_/¯

    • Marked as answer by Ja Som Tuesday, January 07, 2014 9:34 PM
    Tuesday, January 07, 2014 9:28 PM

  • Yes I`m sure... <!DOCTYPE html> <html> <head> <meta charset="utf-8" />

    Actually the PowerShell V3 and later can now parse the DOCTYPE so it should load as XML.

    This loads as XML:

    [xml]'<!DOCTYPE html> <html> <head>  <meta charset="utf-8" /></head></html>'


    ¯\_(ツ)_/¯


    this is something I can work with :) usefull informatin. Thanx jrv
    Tuesday, January 07, 2014 9:35 PM
  • Good - always look at all possibilities.  Remember that ADO and Excel/MSAccess/Office can all import HTML tables directly.

    ¯\_(ツ)_/¯

    Tuesday, January 07, 2014 9:40 PM