Archive

Archive for the ‘Programming’ Category

Powershell script: Invoke-CommandOnADComputers

October 13th, 2014 No comments

Sometimes I need to run some command on bunch of computers. So I’ve created little bit more advanced function to be able to run script block on computers list created from domain:

 


<#
.Synopsis
   This function provides you way to run scriptblock on remote machines in the domain.
.DESCRIPTION
   This function is extension to Cmd-Let Invoke-Command. This function lists computer names in domain
   based on ADSearchBase and Filter parameters. In invoke scriptblock on those computers in the list.
.EXAMPLE
   To restart service "Windows Time" on all machines in domain:
   Invoke-CommandOnADComputers -SearchBase "DC=domain,DC=local" -ScriptBlock { Restart-Service W32Time; }
.EXAMPLE
   To restart service "Windows Time" on all machines which containt number 7 in name:
   Invoke-CommandOnADComputers -SearchBase "DC=domain,DC=local" -Filter 'Name -like "*7*"' -ScriptBlock { Restart-Service W32Time; }
#>

Function Invoke-CommandOnADComputers
{
    [CmdletBinding(SupportsShouldProcess=$True,ConfirmImpact='Low')]
    Param
    (
        # This is Active Directory Search Base to limit selection for computer accounts in domain.
        # It can be for example "OU=Computers,OU=Company Name,DC=domain,DC=local"
        [parameter(Mandatory=$true)]
        [string]
        $SearchBase,

        # Active Directory filter to merge your computer selection in to the detail.
        # It can be for example 'Name -like "Desktop*"'
        [string]
        $Filter = "*",

        # This is scriptblock which should be run on every computer.
        # For example { Restart-Service W32Time; }
        [parameter(Mandatory=$true)]
        [scriptblock]
        $ScriptBlock
    )
    Begin
    {
        #
        # Get list of computer accounts
        #
        Write-Verbose "Getting list of computer from $ADSear"
        try
        {
            [array]$ADComputersList = Get-ADComputer -SearchBase $SearchBase -Filter $Filter -ErrorAction Stop
        }
        catch
        {
            Write-Error -Message "Couldn't search in $SearchBase" -ErrorAction Stop
        }
        #
        # Write number of found computers
        #
        Write-Host "Found $($ADComputersList.Count) computers"
        #
        # If in debug, write list of computers
        #
        Write-Verbose "List of machines:"
        If (!$PSDebugContext)
        {
            foreach ($item in $ADComputersList)
            {
                Write-Verbose " $($item.Name)"
            }
        }
        Write-Verbose "Done with domain computer list"
    }
    Process
    {
        #
        # Let's invoke command on remote computer
        #
        foreach ($ADComputer in $ADComputersList)
        {
            Write-Host $ADComputer.Name
                try
                {
                    Write-Verbose "Invoking scriptblock on computer"
                    Invoke-Command -ComputerName $ADComputer.Name -ScriptBlock { $ScriptBlock } -ErrorAction Stop
                    Write-Host " Scriptblock invoked successful."
                }
                catch
                {
                    Write-Host " Scriptblock invoked UNSUCCESSFUL."
                }
        }
    }
}

You can run it using

Invoke-CommandOnADComputers -SearchBase “DC=domain,DC=local” -ScriptBlock { Restart-Service W32Time; }

and it will read all computer accounts from domain and restart Windows Time service.

Enjoy,

PowerShell: Script to check for logged users

September 16th, 2014 No comments

I’m creating couple powershell scripts which I use in my work. I want to share couple of them with you. So here is a script which look for domain computers and then check who is logged on those online machines.

$ADSearchBase = "OU=Computers,DC=domain,DC=local"
$ADFilter = "*"

Function Get-LoggedUsersOnComputers
  {
  $ADComputersList = Get-ADComputer -SearchBase $ADSearchBase -Filter $ADFilter
  foreach ($ADComputer in $ADComputersList)
    {
    Write-Output $ADComputer.Name
    Try
       {
       $ExplorerProcesses = Get-WmiObject -ComputerName $ADComputer.Name -Class win32_process -Filter "Name='explorer.exe'" -ErrorAction Stop
       }
     Finally
       {
       If ($?)
         {
         foreach ($ExplorerProcess in $ExplorerProcesses)
           {
           Write-Output "  $($ExplorerProcess.GetOwner().User)"
           }
         }
       Else
         {
         Write-Output "  <<< Could not connect"
         }
       }
    }
  }

Get-LoggedUsersOnComputers

If you have any remark on my script, please, let me know. I will be happy to make it more cute 🙂

Run script in elevated mode with active UAC

March 4th, 2013 No comments

I had to run one vbs script on Windows 7 with UAC enabled. This script was implemented as part of Run/RunOnce technology in Windows. When you want some script/application to run everytime you log in or just once you log in, you can use this technology built-in Windows. You can read about it here. Implementation of these registry keys was easy. Problem raised when I found out that script doesn’t run in elevated mode – without administrative privileges.

If you need to run some script in elevated mode, you can right-click on script and select “Run as administrator”. This is fine, but what about script that is part of registries? There is no way to right-click 🙂 You have to use UNDOCUMENTED parameter “runas” of parameter ShellExecute of object Shell.Application. It’s really undocumented on official sites!

Another bad thing of running script in elevated mode is that you cannot access network drives which you have mapped. You need to remap them and then you can use them.

There are nice articles which describe how to run scripts in elevated mode:

This saved me couple hours of fight with scripts 🙂

 

VBS Script: How to find out actual path of running script

March 1st, 2013 No comments

When you need to find out what path is the running script located at you can use following script:

Dim strFullPath, strPath

strFullPath = WScript.ScriptFullName

strPath = Left(strFullPath, InStrRev(strFullPath,”\”))

Enjoy,