Determine SQL Version and Edition using Powershell and WMI

December 8th, 2014

This small Powershell script prompts for a computername and tries to determine the installed version and edition of SQL using WMI.

$comp = Read-Host "Enter Computername:"
Get-WmiObject -ComputerName $comp -Namespace root\Microsoft\SqlServer\ComputerManagement -Class SqlServiceAdvancedProperty | Where-Object {($_.PropertyName -eq 'VERSION') -or ($_.PropertyName -eq 'SKUNAME')} | Format-Table ServiceName, PropertyName, PropertyStrValue -AutoSize
Get-WmiObject -ComputerName $comp -Namespace root\Microsoft\SqlServer\ComputerManagement10 -Class SqlServiceAdvancedProperty | Where-Object {($_.PropertyName -eq 'VERSION') -or ($_.PropertyName -eq 'SKUNAME')} | Format-Table ServiceName, PropertyName, PropertyStrValue -AutoSize
Get-WmiObject -ComputerName $comp -Namespace root\Microsoft\SqlServer\ComputerManagement12 -Class SqlServiceAdvancedProperty | Where-Object {($_.PropertyName -eq 'VERSION') -or ($_.PropertyName -eq 'SKUNAME')} | Format-Table ServiceName, PropertyName, PropertyStrValue -AutoSize
Get-WmiObject -ComputerName $comp -Namespace root\Microsoft\SqlServer\ComputerManagement14 -Class SqlServiceAdvancedProperty | Where-Object {($_.PropertyName -eq 'VERSION') -or ($_.PropertyName -eq 'SKUNAME')} | Format-Table ServiceName, PropertyName, PropertyStrValue -AutoSize

Batch script to detect CD/DVD-rom drive

May 2nd, 2014

Batch script to detect CD/DVD-rom drive


REM Check if we have a CDROM drive
Setlocal EnableDelayedExpansion

echo list vol > diskpart.txt
diskpart /s diskpart.txt > dp_volumes.txt
set hascdrom=0
FOR /F "delims=," %%v in (dp_volumes.txt) do (
rem echo %%v
set str1=%%v
rem echo Line is !str1!
rem echo "x!str1:ROM=!"
rem echo "x!str1!"
if not "x!str1:ROM=!"=="x!str1!" set hascdrom=1
rem echo !hascdrom!
)
if "!hascdrom!"=="0" GOTO nocdrom

:cdrom
echo We have a CD/DVD-rom
goto :EOF

:nocdrom
echo No CD/DVD-rom drive available
goto: EOF

Domain Join using Powershell

November 13th, 2012

Example of how to join a computer (Windows 8) to a domain using PowerShell.


$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList @('ALTIRIS\srv_altiris', (ConvertTo-SecureString -AsPlainText -Force 'P@ssw0rd' ))
Add-Computer -DomainName altiris.local -OUPath 'OU=CORPORATE_COMPUTERS,OU=BELGIUM,DC=altiris,DC=local' -PassThru -Verbose -Credential $credential

CentOS – Launching VMWare Workstation VMs at boot

January 23rd, 2011

I was searching for a solution to launch and suspend VMWare Workstation VMs on a CentOS 5-machine during boot/shutdown.
A script script for launching VirtualBox VMS during boot inspired me to create one for VMWare Workstation.
In this example I have teamed my VMs in a team /vms/my_team.vmtm, it could as well be a single VM (.vmx) that is being launched.
The VM Team will be launched with a different user account as VMWare not allows root to launch VMs.
During shutdown root however can suspend the VM Team, and this is also the action being used during system shutdown.

  1. Create a user vmuser
    useradd vmuser
    passwd vmuser
  2. Create the VMHeadless script. I have teamed all my VMS and will launch/suspend the team /vms/my_team.vmtm
    vi /etc/init.d/vmheadless

    #!/bin/bash
    ### BEGIN INIT INFO
    # Provides:          vmheadless.sh
    # Required-Start:    $remote_fs $syslog
    # Required-Stop:     $remote_fs $syslog
    # Default-Start:     2 3 4 5
    # Default-Stop:      0 1 6
    # chkconfig: 2345 99 20
    # Short-Description: Start VM
    # Description:       Start/stop the virtual machines
    ### END INIT INFO
     
    MACHINE_NAME="/vms/my_team.vmtm"
    VM_USER="vmuser"
    RETVAL=0
    LD_LIBRARY_PATH=/usr/lib/vmware:$LD_LIBRARY_PATH
    PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin
     
    id=`id -u`
    if  [ "$id" != "0" ] ; then
       echo "This script must be run as root" 1>&2
       exit 1
    fi
     
    # Load the VERBOSE setting and other rcS variables
     [ -f /etc/default/rcS ]  && . /etc/default/rcS
     
    # Load the VERBOSE setting and other rcS variables
    #. /lib/init/vars.sh
     
    # Define LSB log_* functions.
    # Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
    . /lib/lsb/init-functions
     
    # Get function from functions library
    . /etc/init.d/functions
     
    # Load network defaults. Use this if there is any extra network stuff to do first.
     
    case "$1" in
    start)
       su $VM_USER -c "/usr/bin/vmrun start $MACHINE_NAME nogui"
            RETVAL=0
      echo "Started VM Headless RETVAL=($RETVAL)"
            ;;
    stop)
      /usr/bin/vmrun suspend "$MACHINE_NAME"
            RETVAL=$?
     echo "Suspended VM Headless RETVAL=($RETVAL)"
            ;;
    status)
      ps=`ps -ef | grep vmware-vmx | grep -v grep | wc -l`
      if  [ "$ps" -gt 0 ]  ; then
        echo "$ps VMS started"
        RETVAL=1
      else
        echo "VMS not running"
        RETVAL=0
      fi
            ;;
    restart)
      /usr/bin/vmrun suspend "$MACHINE_NAME" nogui
            RETVAL=$?
     echo "Suspended VM Headless RETVAL=($RETVAL)"
      su backup -c "/usr/bin/vmrun -T ws start $MACHINE_NAME nogui"
            RETVAL=$?
      echo "Started VM Headless RETVAL=($RETVAL)"
            ;;
    *)
            echo "Usage: $0 { start | stop }"
            RETVAL=1
            ;;
    esac
    exit $RETVAL
    
  3. Enable VMHeadless during boot
    chkconfig –add vmheadless
    chkonfig –level 2345 vmheadless on
  4. Launch the VMHeadless daemon, and thus launching the VM Team
    service vmheadless start

PS – Disable Unidentified network for VM nics

October 6th, 2010

This script adds the *NdisDeviceType registry value with value 1 to the keys of the VMWare network cards.
Afterwards it disables and enables the networkcards to let the changes take effect.

$nics = gci "HKLM:\SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"
$nics | foreach-object -process {
    $devInstanceId = $_.getvalue("DeviceInstanceID")
    if($devInstanceId -match "VMWARE"){
        Write-Host $_.Name
        $regpath = ( $_.name ) -replace("HKEY_LOCAL_MACHINE","HKLM:")
        new-itemproperty -path $regpath -name "*NdisDeviceType" -value 1 -PropertyType "DWORD"
    }
}
 
 $wminics = get-wmiobject win32_networkadapter | where-object {$_.name -like "*vmware*" }
 $wminics | foreach-object -process { 
        
     write-host -nonew "Disabling $($_.name) ... "
     $result = $_.Disable() 
     if ($result.ReturnValue -eq -0) { write-host " success." } else { write-host " failed." } 
        
     write-host -nonew "Enabling $($_.name) ... "
     $result = $_.Enable() 
     if ($result.ReturnValue -eq -0) { write-host " success." } else { write-host " failed." } 
 }

Outlook VBA – remove reminders

August 27th, 2010

I synchronize my Windows Mobile Device with my corporate-exchange account. This way my calendar stays nicely up to date and gives me reminders for the tasks I have to do.

However I find it rather a hassle that I receive reminders for certain activities like holidays. Therefore I have written a small macro that disables the reminders for all future calendar entries with a certain subject.

Private Sub RemoveReminders(sProject As String)
Dim fldMailbox As MAPIFolder
Dim fldCalendar As MAPIFolder
 
Dim objItem As AppointmentItem
Dim iCntr As Integer
iCntr = 0
 
Set fldMailbox = Session.Folders(sMailboxName)
Set fldCalendar = fldMailbox.Folders("Calendar")
Set mcolCalItems = fldCalendar.Items
 
For Each objItem In mcolCalItems
If objItem.start > Now() Then
If objItem.ReminderSet = True Then
    If InStr(objItem.Body, sProject) > 0 Then
    iCntr = iCntr + 1
With objItem
.ReminderSet = False
.Save
End With
 
objItem.Save
End If
End If
End If
Next
 
MsgBox "Modified " & iCntr & " calendar entries"
End Sub
 
Public Sub RemoveHolidayReminders()
RemoveReminders ("Holiday")
End Sub

ESXi 3.5 and Server 2003 dualboot

January 31st, 2010

After some testing I managed to create a dualboot setup with ESXi 3.5 and Windows Server 2003.

  1. Install ESXi to harddisk 1
  2. Install Windows Server 2003 to harddisk 2. Delete the existing partition on harddisk 2 if ESXi has created one.
    On the first reboot during the installation you should get an error “NTLDR is missing”
  3. Boot with a live linux cd-rom, eg KNOPPIX
  4. (Re-)install syslinux bootloader to boot partition (Hypervisor0)
    sudo syslinux /dev/hda1
    file is read only. overwrite anyway (y/n)? y
    sudo mkdir /mnt/Hypervisor0
    sudo mount /dev/hda1 /mnt/Hypervisor0
    vi /mnt/Hypervisor0/syslinux.cfg
    
    

    original:

    default safeboot.c32
    
    

    modified:

    default menu.c32
    menu title Dual boot
    timeout 100
    label esx
    menu label ESXi 3.5
    COM32 safeboot.c32
    LABEL win
    MENU LABEL MS Windows Server 2003
    COM32 chain.c32
    APPEND boot ntldr=/NTLDR
    
    
  5. Copy syslinux modules menu.c32 and chain.c32 to boot partition (Hypervisor0)
    Use locate to find the folder on the live cd that contains the modules, eg locate menu.c32

    cp /usr/lib/syslinux/menu.c32 /mnt/Hypervisor0
    cp /usr/lib/syslinux/chain.c32 /mnt/Hypervisor0
    
    
  6. Reboot

Tool to query SQL databases

January 15th, 2010

For some tasks it is useful to run a custom query against a database.
The application using the database perhaps does not have the ability to generate certain reports.
Using SQL manager is a viable option, but then everyone who needs to have this installed to be able to run a query.
It is however possible to create some Excel-files which have the queries embedded.

But as an alternative solution I have created this PowerShell app.
It is a GUI-based tool allowing you to select a saved script or enter a custom query and run it.
The output is by default displayed in a datatable but the output can also be exported to an Excel-document.

The available SQL servers are defined in servers.xml
And to avoid the hassle of selecting a server and database after selecting a script you can predefine a combination of a shortname, server and database in shortnames.xml
Eg. if you have a SQL-file hlp_openincidents.sql and hlp is defined in shortnames.xml with server set to SQLSERVER and database to HELPDESK the tool will autoselect the server: SQLSERVER and the database: HELPDESK

SQL_tool.zip (102 downloads)

Script software deployment in PowerShell

January 10th, 2010

This is an example in PowerShell of how you can schedule the installation a software package by Altiris DS.
Instead of using the API, the command-line tool axsched is being called to schedule the software package.

function DeploySoftware
{
    param( [String] $pcname,  [String] $package,  [String] $nexttime,  [String] $folder)
    #Write-Host "Deploy $pcname '$package' /t $nexttime /f '$folder'"
    #\\ALTIRIS\express\axsched.exe "$pcname" "$package" / t "$nexttime" / f "$folder"
         
    $StartInfo = New-Object System.Diagnostics.ProcessStartInfo
    $StartInfo.CreateNoWindow = $true
    $StartInfo.UseShellExecute = $false
    $StartInfo.FileName = "\\ALTIRIS\express\axsched.exe"
    $StartInfo.WorkingDirectory = "C:\Temp"
    $StartInfo.Arguments = "`"$pcname`" `"$package`" /t `"$nexttime`" /f `"$folder`""
    $p =  [System.Diagnostics.Process] ::Start($StartInfo)
    $p.WaitForExit()
    if ($p.ExitCode -eq 0) { $TRUE } else { $FALSE }
}
#This function adds a number of minutes to the given date time and outputs the addition in the right format for AxSched.
function Get-ScheduleTime
{
    param( [System.DateTime]  $starttime,  [int] $minutes)
    #$minutes = 12
    $tspan = New-Object System.TimeSpan(0, 0, $minutes, 0)
    $addtime =  [System.DateTime] ::op_Addition($starttime, $tspan)
    #"2008-10-20 15:00"
    $y = $addtime.Year
    $mo = $addtime.Month
    $d = $addtime.Day
    $h = $addtime.Hour
    $mi = $addtime.Minute
    $schedtime = "$y"
    $schedtime += "-"
    $schedtime += TwoDecimal("$mo")
    $schedtime += "-"
    $schedtime += TwoDecimal("$d")
    $schedtime += " "
    $schedtime += TwoDecimal("$h")
    $schedtime += ":"
    $schedtime += TwoDecimal("$mi")
    $schedtime
}
#Simple function to convert a single decimal to a two decimal, eg 7 becomes 07
function TwoDecimal
{
    param( [String] $Number)
    while ($number.Length -lt 2) { $number = "0$number" }
    $number
}
$now =  [System.DateTime] ::Now
$pcname = "COMP007"
$jobname = "Install Outlook 2007"
$jobfolder = "Software"
#The installation of the package needs to be started after 5 minutes.
$nexttime = Get-ScheduleTime $now 5
DeploySoftware $pcname $jobname $nexttime $jobfolder

Powershell check requirements and load addins

January 10th, 2010

Powershell excerpts of how to check if .NET FrameWork 3.5, Quest AD, Altiris ASDK is installed

First the functions that execute the installer.

function Execute-Installer()
{
    param( [String] $parameters, [String] $msiworkingdir)
    $msiworkingdir = Resolve-Path $msiworkingdir
    $StartInfo = New-Object System.Diagnostics.ProcessStartInfo
    $StartInfo.CreateNoWindow = $true
    $StartInfo.UseShellExecute = $false
    $StartInfo.FileName = "c:\windows\system32\msiexec.exe"
    $StartInfo.WorkingDirectory = "$msiworkingdir"
    $StartInfo.Arguments = "$parameters"
    $p =  [System.Diagnostics.Process] ::Start($StartInfo)
    $p.WaitForExit()
    if ($p.ExitCode -eq 0) { $TRUE } else { $FALSE }
}
 
function Execute-Program()
{
    param( [String] $parameters, [String] $program)
    Write-Host "Execute-Program $program $parameters"
    #Write-Host "MSI WorkingDir: $msiworkingdir"
    #$msiworkingdir = Resolve-Path $msiworkingdir
    $program = Resolve-Path $program
    Write-Host "Program: $program"
    $StartInfo = New-Object System.Diagnostics.ProcessStartInfo
    $StartInfo.CreateNoWindow = $true
    $StartInfo.UseShellExecute = $false
    $StartInfo.FileName = $program
    $StartInfo.Arguments = "$parameters"
    $p =  [System.Diagnostics.Process] ::Start($StartInfo)
    $p.WaitForExit()
    if ($p.ExitCode -eq 0) { $TRUE } else { $FALSE }
}

The code that checks if .NET FrameWork 3.5 is installed.
A messagebox will be displayed if it is not installed.
If users answers yes to the messagebox the requirement will be installed.

#region Check if .NET 3.5 is installed (Requirement for QuestAD and AltirisASDK
function Check-DotNet35{
Write-Host "Check-DotNet35"
$net35 = get-itemproperty "hklm:\\SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.5"
if($net35 -eq $null){
Write-Host ".NET 3.5 is not installed."
$install =  [Windows.Forms.MessageBox] ::Show(".NET 3.5 Framework is not installed. This is required. Would you like to install it?", "My Application",  [Windows.Forms.MessageBoxButtons] ::YesNo,  [Windows.Forms.MessageBoxIcon] ::Question)
if ($install -eq  [Windows.Forms.DialogResult] ::Yes){
Execute-Program "/PASSIVE /NORESTART" "D:\Software\DotNet\3.5\dotnetfx35SP1.exe"
}
}else{
Write-Host "DotNet 3.5 FrameWork is installed"
}
}
Check-DotNet35
#endregion

The code to check if Quest AD is installed.
A messagebox will be displayed if it is not installed.
If users answers yes to the messagebox the requirement will be installed.
Also if the users has an outdated version he will receive a messagebox asking to perform an upgrade.

#region Load Quest AD plugin
function Load-QuestAD-Plugin
{
Write-Host "Load-QuestAD-Plugin"
$retVal = (Get-PSSnapin Quest.ActiveRoles.ADManagement 2>$null)
$qadversion = "1.2.2.1254"
#Write-Host $retVal
if ($retVal -eq $null)
{
Write-Host "Quest.ActiveRoles.ADManagement"
Add-PSSnapin Quest.ActiveRoles.ADManagement
$retVal = "$?"
if ($retVal -eq $false)
{
$install =  [Windows.Forms.MessageBox] ::Show("Quest.ActiveRoles.ADManagement is not installed. Would you like to install it?", "My Application",  [Windows.Forms.MessageBoxButtons] ::YesNo,  [Windows.Forms.MessageBoxIcon] ::Question)
if ($install -eq  [Windows.Forms.DialogResult] ::Yes)
{
Write-Host "Installing Quest.ActiveRoles.ADManagement"
Write-Host "msiexec.exe /i `"$WorkingDir\Requirements\arps.$qadversion.msi`" /qn /norestart /l*c:\windows\temp\arsps.log"
$retVal = Execute-Installer "/i `"$WorkingDir\Requirements\arps.$qadversion.msi`" /qn /norestart /l* c:\windows\temp\arsps.log" "c:\temp"
if($retVal -eq $true){
Write-Host "Install finished"
}
}
else
{
Write-Host "No install of Quest.ActiveRoles.ADManagement"
}
}
else
{
Write-Host "QAD installed"
$pssnapinversion = (Get-PSSnapin Quest.ActiveRoles.ADManagement).version
$textversion = $pssnapinversion.Major.tostring() + "." + $pssnapinversion.Minor.tostring() + "." + $pssnapinversion.Build.tostring() + "." + $pssnapinversion.Revision.tostring()
Write-Host "Required version: $qadversion - Current version: $textversion "
if ($textversion -ne $qadversion)
{
$install =  [Windows.Forms.MessageBox] ::Show("Quest.ActiveRoles.ADManagement is not up to date. Would you like to update it?", "My Application",  [Windows.Forms.MessageBoxButtons] ::YesNo,  [Windows.Forms.MessageBoxIcon] ::Question)
#if ($install.tolower() -eq "y")
if ($install -eq  [Windows.Forms.DialogResult] ::Yes)
{
Remove-PSSnapin Quest.ActiveRoles.ADManagement
Write-Host "Installing Quest.ActiveRoles.ADManagement"
Write-Host "msiexec.exe /i `"$WorkingDir\Requirements\arps.$qadversion.msi`" /qn /norestart /l*c:\windows\temp\arsps.log"
$retVal = Execute-Installer "/i `"$WorkingDir\Requirements\arps.$qadversion.msi`" /qn /norestart /l* c:\windows\temp\arsps.log" "c:\temp"
if($retVal -eq $true){
Write-Host "Install finished"
}
}
else
{
Write-Host "No install of Quest.ActiveRoles.ADManagement"
}
}
}
}
}
Load-QuestAD-Plugin
#endregion

Check if Altiris ASDK for NS is installed.
A messagebox will be displayed if it is not installed.
If users answers yes to the messagebox the requirement will be installed.
If it is already installed the connections will be made to the server.

#region Load Altiris ASDK
function Load-AltirisASDK
{
Write-Host "Load-AltirisASDK"
$altirisserver="ALTIRIS"
$global:nsColl = New-Object -comObject Altiris.ASDK.NS.CollectionManagement
if($? -eq $false){
Write-Host "AltirisASDK is not installed"
$install =  [Windows.Forms.MessageBox] ::Show("Altiris ASDK is not installed. Would you like to install it?", "My Application",  [Windows.Forms.MessageBoxButtons] ::YesNo,  [Windows.Forms.MessageBoxIcon] ::Question)
#if ($install.tolower() -eq "y")
if ($install -eq  [Windows.Forms.DialogResult] ::Yes)
{
#Execute-Program "/S" "$WorkingDir\Requirements\Altiris_ASDK_1_4_209.exe"
$retVal = Execute-Installer "/i `"$WorkingDir\Requirements\Symantec_ASDK_NS_COM_x86.msi`" /qn /norestart /l* c:\windows\temp\asdkNS.log" "c:\temp"
if($retVal -eq $true){
Write-Host "ASDK has been installed"
}else{
Write-Host "ASDK installation failed"
}
}
 
}else{
$global:nsItem = New-Object -comObject Altiris.ASDk.NS.ItemManagement
$global:nsRes = New-Object -comObject Altiris.ASDK.NS.ResourceManagement
$global:nsReport = New-Object -comObject Altiris.ASDK.NS.ReportManagement
$global:nsReport.targetserver = $altirisserver
$global:nsReport.authenticate()
$global:nsItem.targetserver = $altirisserver
$global:nsItem.authenticate()
$global:nsColl.targetserver = $altirisserver
$global:nsColl.authenticate()
$global:nsRes.targetserver = $altirisserver
$global:nsRes.authenticate()
}
}
Load-AltirisASDK
#endregion