Comments

7 comments

  • Stephen Valdinger

    $env:COMPUTERNAME will pull in the hostname the script is currently running on.

    0
    Comment actions Permalink
  • joe kent

    If the host is off then I can't get that environment variable. I have code that will send wake on lan but I need the COMPUTERNAME to get the mac address that is in a database.

    0
    Comment actions Permalink
  • Stephen Valdinger

    You should be able to set your offline settings to wake the machine before trying the deployment, negating the need for extra code. Little confused as to why you would hand that functionality off to another process/script, when it is baked into the product and works very well.

    0
    Comment actions Permalink
  • joe kent

    I need PDQ Inventory to be able to do wake.

    0
    Comment actions Permalink
  • Stephen Valdinger

    Ah man, you don't have Inventory?! You really should it's a fantastic compliment to Deploy.

    How are you deploying to machines currently? Just typing them in or pulling from Active Directory? Is there any sort of order to how you are deploying your script to them? I'm unaware of any direct $(TargetComputer) variable in Deploy, though one of the guys may chime in there.

     

    You could possibly wrap it all up into Powershell in and of itself using pdqdeploy.exe, but I don't really want to head down that road if it isn't something you are comfortable with.

    0
    Comment actions Permalink
  • joe kent

    Mostly just typing them in. What are the details on using pdqdeploy.exe?

    0
    Comment actions Permalink
  • Stephen Valdinger

    And down the rabbit hole we go!

     

    Ok, so Powershell is, well, really powerful!

    With the active directory module loaded on a computer you can do things like:

    Get-ADComputer testpc01

    That's going to return an object containing all the details about that particular computer. You can narrow you search with the -SearchBase parameter and give it a specific OU that you want to look at. 

    So for example you have an Accounting OU in a domain called example.local. You could specify all the computers in that OU like this:

    Get-ADComputer * -SearchBase "OU=Accounting,DC=example,DC=local"

    That's going to give you a return output of 1 object per computer in that OU. The cool thing about powershell is we can filter that down EVEN MORE, so it only returns us the Name property, since that is all we really care about here. That's going to look like this:

    Get-ADComputer * -SearchBase "OU=Accounting,DC=example,DC=local" | Select-Object Name

    Boom you have a list of all your names! Well, now what? You say you have a script and/or function that takes a computer name, does a look up on the MAC, and performs a WoL. Let's look at an example of that, with some creative liberty in the code just for example purposes.

    $computers = Get-ADComputer * -SearchBase "OU=Accounting,DC=example,DC=local" | Select-Object Name

    Foreach($computer in $computers){

    #I'm making up the name of your script/function here, but I'm sure you can fill in the blanks

    Send-WoLPacket -Computername $computer.Name

    }

    The code above is going to one at a time execute that Send-WoLPacket function against the computer name that it is currently working on.

    Now, onto PDQ Deploy. They've got a handy command-line version that you can leverage. There are a couple of things to note on it, and I'll kind of hit them as we go.

    The Syntax for the command looks something like this:

    pdqdeploy.exe Deploy -Package "Package name" -ScheduleName "Schedule Name (useful for many packages at once) -Targets "Target Computer name"

    That command needs to be run on the server with PDQ Deploy installed, which leads me to my first gotcha. You're gonna have to have that Active Directory module on the server, or some way to send that data to PDQ Deploy. Thankfully, Powershell has your back.

     

    First way: Running it on your machine (if you have RSAT installed, you'll have the AD module).

    Let's take a look again at getting that computer name.

    $computers = Get-ADComputer * -SearchBase "OU=Accounting,DC=example,DC=local" | Select-Object Name

    Foreach($computer in $computers){

    Invoke-Command -Computername pdqdeployserver -Scriptblock { pdqdeploy.exe Deploy -Package ExamplePackage -Targets $args[0]} -ArgumentList $computer.Name

    }

    What I've just done is told powershell that "For every computer name you are chewing on, execute a pdqdeploy.exe command on the pdqdeploy server." The server isn't going to know what the heck $computer.Name is though, that's what $args[0] is doing. The -ArgumentList parameter of Invoke-Command is the Powershell way of passing that local variable information to the remote endpoint. It's positional, so $args[0] would be the first item listed after -ArgumentList, and you can comma separate as many as you need. Just remember that the first item is [0], the second is [1] and so on.

    You could also Install RSAT onto the Deploy server if you are so incline, or you could use Implicit remoting to create a temporary copy of the AD module on the machine running the script. That's kind of an advanced method, and possibly outside the scope of this document, but if you are interested you can find more information about it here:

    http://windowsitpro.com/blog/powershell-implicit-remoting-never-install-module-again

    So how do we put it all together? 

     

    Well, we have to combat the issue of the downtime between sending the WoL packet and sending the pdqdeploy.exe command to the server.  I'll provide an example of how it all would look tied together if I was going to roll this out in my environment

    $computers = Get-ADComputer * -SearchBase "OU=Accounting,DC=example,DC=local" | Select-Object Name

    Foreach($computer in $computers){

    Send-WoLPacket -Computername $computer.Name

    Do{

    Out-Null

    }

    Until((Test-Connection -Computername $computer.name -Count 10 -Quiet))

    Invoke-Command -Computername pdqserver -ScriptBlock { pdqdeploy.exe Deploy -Package ExamplePackage -Targets $args[0] } -ArgumentList $computer.Name

    }

     

    Again, this is all just an example, and sorry for the huge wall of text, but without knowing your skill level in the shell I wanted to be quite thorough, and also for posterity sake someone else may stumble on this from google and find it useful.

    Here are some helpful documentation links as well. I did the code from memory, so please reference this when making your final product so you get the syntax right for the command line utility.

    https://documentation.pdq.com/PDQDeploy/12.1.0.0/

    And here is more than you ever wanted to know about Invoke-Command

    https://www.pdq.com/powershell/Invoke-Command/

     

    Happy Deploying!

    0
    Comment actions Permalink

Please sign in to leave a comment.