Ricky in Melbourne - Enjoy Learning

PowerShell to Find, Stop, Disable and Remove Windows Service from remote computers

Last time, I updated an internet PowerShell script to allow us Stop and Disable a specific Windows Service on remote computers.

This time, I’m in a more further scenario where I have to match the below criteria

Find specific Windows Service

Not Exist: Stop and show result

If exist:

            Stop Service

            Disable Service

            Delete Service

            Show result

The little challenge here is PowerShell doesn’t support removing Windows Service, so the easiest way is just using the building windows SC command

So let’s use another readable way approach to the script this time.

It’s not a fancy script, just post here to help people out.

——————————————————————————————————————————————————————————————————————–

$ServerListPath = read-host ‘?Please provide the full path of the serverlist file, like c:\server.txt’¡¥ #Prompt to input the server list

$Servers = get-content -Path $ServerListPath

$Service = read-host ‘?Please provide the service name to be removed’¡¥ #Prompt to input the service name, NOT the description name

function Confirm-WindowsServiceExists($Service) #Detect Service Existence

{

if (Get-Service -Name $Service -Computername $server -ErrorAction SilentlyContinue)

{

Write-Host "Service $Service Exists on $server" -ForegroundColor Green

return $true

}

Write-Host "Service $Service does not exist on $server" -ForegroundColor Red

return $false

}

function Remove-WindowsServiceIfItExists($Service) #Remove Service if exist

{

$exists = Confirm-WindowsServiceExists $Service

if ($exists)

{

Write-host "stopping Service $Service from $server" -ForegroundColor Green

sc.exe \\$server stop $Service #Stop Service

Start-Sleep -s 10 #Pause 10 seconds to wait for service stopped

Write-host "Disabling Service $Service from $server" -ForegroundColor Green

sc.exe \\$server config $Service start= disabled #Disable Service

Write-host "Kill MMC Service from $server" -ForegroundColor Green

taskkill /s $server /IM mmc /f #Kill mmc if exist which will prevent to delete service

Write-host "Removing Service $Service from $server" -ForegroundColor Green

sc.exe \\$server delete $Service #Delete Service

Write-host "Querying Service $Service from $server" -ForegroundColor Green

sc.exe \\$server qc $Service #Query Service again

}

}

ForEach ($server in $servers) {Remove-WindowsServiceIfItExists($Service)} #Loop

—————————————————————————————————————————————————————————————-

 

By Ricky Gao (高俊) on September 12, 2014 | Scripts, Tech | A comment?

PowerShell change WinXP product key and get reports

This time I was in a scenario where I need to bulk updating the Windows XP machine’s product key and get the reports back.

I know you may wondering from the tile with below questions

Does WinXP support PowerShell?

How do you update the WinXP product key with PowerShell?

Well, the answer here is NO, so actually I’m use PowerShell here for the report purpose, I still need to use PowerShell to call some VB script to change the keys Smile

Preparations:

1. GetKey.vbs

This VB script is used to get the current system or remote system’s Product Key, support both Windows XP and Windows 7 (Only for Volume License Key I believe, need testing on Windows 8 VLK)

The original script was from here which only support getting the remote computer’s key

I’ve updated the script and made this available to be able query local machine’s product key as well



‘ Find Product Activation Key on Remote Machine

‘ Got this from a posting by ‘Alatar1′ at www.theeldergeek.com

‘ I just added the inputbox – Rob

‘ Updated by www.RickyGao.com to support running locally

‘ Usage: save to GetKey.vbs, run without parameter will get the key from local machine, run with computer name will get the key from remote computer.

‘ Example Local Key: cscript.exe getkey.vbs

‘ Example Remote Key: cscript.exe getkey.vbs computername

If Wscript.Arguments.Count = 0 Then

strComputer = "."

Else

strCOmputer = Wscript.Arguments.Item(0)

End If

Dim Digits (24)

Digits (0) = "B" : Digits (1) = "C": Digits (2) = "D": Digits (3) = "F":

Digits (4) = "G": Digits (5) = "H": Digits (6) = "J": Digits (7) = "K":

Digits (8) = "M": Digits (9) = "P": Digits (10) = "Q": Digits (11) = "R":

Digits (12) = "T": Digits (13) = "V": Digits (14) = "W": Digits (15) = "X":

Digits (16) = "Y": Digits (17) = "2": Digits (18) = "3": Digits (19) = "4":

Digits (20) = "6" : Digits (21) = "7" : Digits (22) = "8": Digits (23) = "9"

Dim HexBuf (100), HexDigitalPID (15)

Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")

objReg.GetBinaryValue &H80000002, "SOFTWARE\Microsoft\Windows NT\CurrentVersion\", "DigitalProductId", HexBuf

‘ Extract Relevant Section of Digital Product ID

StartOffset = 52 : EndOffset =67

For i = StartOffset to EndOffset

HexDigitalPID (i-StartOffset) = HexBuf(i)

next

‘ Convert Encoded Product ID to Activation Key

dLen = 29 : sLen = 15

KEYSTRING =""

for i=dLen-1 to 0 step -1

if ((i + 1) mod 6) = 0 then

KEYSTRING = KEYSTRING & "-"

else

HN = 0

For N = (sLen -1) to 0 step -1

Value = ( (HN *2^8 ) Or HexDigitalPID (N))

HexDigitalPID (N) = Value \ 24

HN = (Value mod 24)

next

KEYSTRING = KEYSTRING & Digits(HN)

end if

next

KEYSTRING2 = StrReverse (KEYSTRING)

WScript.Echo KEYSTRING2



2. ChangeVLKeySP1.vbs (ChangeVLKey2600.vbs for WinXP/Win2003 below SP1)

See more details from Microsoft KB328874

3. PSExec

Get the powerful PSExec.exe from Microsoft here

4. ChangeKey.ps1

Replace XXXXX-XXXXX-XXXXX-XXXXX-XXXXX to your new key and save below script code to ChangeKey.ps1



$OutPut = @() #Makes an array to hold all the object of the same fields

$ServerListPath = read-host ‘Please provide the full path of the serverlist file, like c:\server.txt’ #Prompt to input the server list

$ServerList = get-content -Path $serverlistpath #Get the server list

foreach ($ServerName in $ServerList)

{

    if (test-connection -computername $ServerName -quiet -count 2) #Check remote connection

    {

    $OldKey = cscript.exe .\getkey.vbs $ServerName //nologo #Get current product key

    copy .\ChangeVLKeySP1.vbs \\$ServerName\c$\ #Copy change key script to local c drive

    .\PsExec.exe -accepteula \\$ServerName cscript.exe C:\ChangeVLKeySP1.vbs XXXXX-XXXXX-XXXXX-XXXXX-XXXXX #Change product key

    del \\$ServerName\c$\ChangeVLKeySP1.vbs #delete the change key script

    $NewKey = cscript.exe .\getkey.vbs $ServerName //nologo #Get new product key

    }

else

{

$OldKey = "NoConnection"

$NewKey = "NoConnection"

}

$FinalResult = New-Object PSObject

Add-Member -inputObject $FinalResult -memberType NoteProperty -name “ServerName” -value $ServerName

Add-Member -inputObject $FinalResult -memberType NoteProperty -name “OldKey” -value $OldKey

Add-Member -inputObject $FinalResult -memberType NoteProperty -name “NewKey” -value $NewKey

$OutPut += $FinalResult

$FinalResult | ft -autosize

}

$OutPut | Export-Csv -noTypeInformation -path C:\Result.csv #report



5. Copy all of the above 4 files: GetKey.vbs, ChangeVLKeySP1.vbs/ChangeVLKey2600.vbs, PSExec.exe, ChangeKey.ps1 to any local folder

Too many scripts? YES, it is Windows XP which doesn’t support PowerShell, I can still recall back to the old days how hard we remote managing computers.

Anyway, it is just the way it is.

Now it’s time to rolling them out:

6. Open PowerShell console

7. Navigate to the local folder

8. Run .\ ChangeKey.ps1

9. Output will looks like below

clip_image002

10. Report is in result.csv

clip_image003

By Ricky Gao (高俊) on August 4, 2014 | Scripts, Tech | A comment?

PowerShell get WMI memory usage report

I was in a scenario where we have some WMI memory leak on the server, so I developed below script to help me get the remote server WMI memory usage report everyday

$OutPut = @() #Makes an array to hold all the object of the same fields

$ServerListPath = read-host ‘Please provide the full path of the serverlist file, like c:\server.txt’ #Prompt to input the server list

$ServerList = get-content -Path $serverlistpath #Get the server list

foreach ($ServerName in $ServerList)

{
    if (test-connection -computername $ServerName -quiet -count 2)
    {
       $WinmgmtPID = Invoke-Command -ComputerName $ServerName -ScriptBlock {(get-wmiobject win32_service -ErrorAction SilentlyContinue | where { $_.name -eq ‘winmgmt’}).processID} #Get WMI service PID
       $Wmiprocess = Invoke-Command -ComputerName $ServerName -ScriptBlock {get-process -id $args[0] -ErrorAction SilentlyContinue} -ArgumentList $winmgmtPID #Get WMI process data

       $MemoryKB = $Wmiprocess.WorkingSet64/1KB #Convert to KB
       $MemoryKB = “{0:N0}” -f $MemoryKB #Format
    }
    else
    {
       $MemoryKB = "NoConnection"
    }

       $FinalResult = New-Object PSObject
       Add-Member -inputObject $FinalResult -memberType NoteProperty -name “ServerName” -value $ServerName
       Add-Member -inputObject $FinalResult -memberType NoteProperty -name “Winmgmt Mem(Private Working Set)” -value $MemoryKB

       $OutPut += $FinalResult
       $FinalResult | ft -autosize
}

$OutPut | Export-Csv -noTypeInformation -path C:\Result.csv
$OutPut | Out-GridView -Title “Result” #GUI View

 

By Ricky Gao (高俊) on August 3, 2014 | Scripts, Tech | A comment?

The relationship between TOGAF, PMP and ITIL

When it comes to high level framework and process, especially in IT industry, people always talk about TOGAF, PMP, Prince2 and ITIL, which confusing us all the time

Let’s have a look on the definition of each concept

TOGAF is a Architecture framework

PMP or Prince2 are the Project Management framework

ITIL is a IT Service framework

I also found below diagram can help me better understanding the relationship between them

image

image

image

In addition, I’ve found a really good TOGAF overview video, highly recommended, you will get a much better and clear understanding between different TOGAF concepts

Hopefully this could help

By Ricky Gao (高俊) on July 29, 2014 | ITIL, PMP, TOGAF | A comment?

PowerShell check file exist, folder size, SCCM client site code and USB disk space

Although I’m not a script specialist, but I cannot deny that PowerShell is a really, really good script platform across all Microsoft product, especially since 2012 products series. Sharing can always help you learn better, so today I would like to share out one of my simple PowerShell script Simple means easy to understand

 

$OutPut = @() #Makes an array to hold all the object of the same fields

$ServerListPath = read-host ‘Please provide the full path of the serverlist file, like c:\server.txt’ #Prompt to input the server list

$ServerList = get-content -Path $serverlistpath #Get the server list

foreach ($ServerName in $ServerList)

{

if (test-connection -computername $ServerName -quiet -count 2) #Test server connection

{

$CCMClientClass = [wmiclass]"\\$ServerName\root\ccm:sms_client"

$CCMSiteCode = $CCMClientClass.GetAssignedSite().sSiteCode #Get SCCM client site code

$LocalFolderPath = “c:\localfolder“ #Define local Folder on remote server path

$LocalFolderSize = Invoke-Command -ComputerName $ServerName -ScriptBlock {Get-ChildItem -path $args[0] -recurse | Measure-Object -Sum length -ErrorAction SilentlyContinue} -ArgumentList $LocalFolderPath #Invoke local command on remote server and pass local argument to get the local folder size

$LocalFolderSizeMB = $LocalFolderSize.sum/1MB #Convert size to MB

$LocalFolderSizeMB = “{0:N1}” -f $LocalFolderSizeMB #Format MB size to show 1 digital after point

$UNCFolderPath = “\\$servername\c$\uncfolder“ #Define UNC folder path

$UNCFolderSize = Get-ChildItem -path $UNCFolderPath -recurse | Measure-Object -Sum length -ErrorAction SilentlyContinue #Get UNC folder size

$UNCFolderSizeMB = $UNCFolderSize.sum/1MB #Convert size to MB

$UNCFolderSizeMB = “{0:N2}” -f $UNCFolderSizeMB #Format MB size to show 2 digital after point

$USBDriveLetter = $USBDisk.driveletter

$USBDisk = Invoke-Command -ComputerName $ServerName -ScriptBlock {Get-WmiObject -class Win32_Volume -Filter "DriveType=’2’" -ErrorAction SilentlyContinue} #Invoke local command on the remote server to get the USB disk information to avoid remote WMI timeout when USB corrupt

$USBUsedSpace = $USBDisk.capacity – $USBDisk.freespace #Calculate the USB disk used space

$USBCapacityGB = $USBDisk.capacity/1GB #Format size to GB

$USBCapacityGB = “{0:N1}” -f $USBCapacityGB #Format GB to show 1 digital after point

$USBUsedSpacebytes = “{0:N0}” -f $USBUsedSpace #Format size to show all digital

$file = Invoke-Command -ComputerName $ServerName -ScriptBlock {Test-Path C:\file.txt} #check target file existence

}

else #If no connection, return below value

{

$CCMSiteCode = "NoConnection"

$LocalFolderSizeMB = "NoConnection"

$UNCFolderSizeMB = "NoConnection"

$USBDriveLetter = "NoConnection"

$USBCapacityGB = "NoConnection"

$USBUsedSpacebytes = "NoConnection"

$file = "NoConnection"

}

$FinalResult = New-Object PSObject

Add-Member -inputObject $FinalResult -memberType NoteProperty -name “ServerName” -value $ServerName #Insert server name

Add-Member -inputObject $FinalResult -memberType NoteProperty -name “SCCMSiteCode” -value $CCMSiteCode #Insert SCCM client site code

Add-Member -inputObject $FinalResult -memberType NoteProperty -name “LocalFolderSize(MB)” -value $LocalFolderSizeMB #Insert Local folder MB size

Add-Member -inputObject $FinalResult -memberType NoteProperty -name “UNCFolderSize(MB)” -value $UNCFolderSizeMB #Insert UNCfolder MB size

Add-Member -inputObject $FinalResult -memberType NoteProperty -name “USBDriveLetter” -value $USBDriveLetter #Insert USB disk driver letter

Add-Member -inputObject $FinalResult -memberType NoteProperty -name “USBCapacity(GB)” -value $USBCapacityGB #Insert USB capacity GB Size

Add-Member -inputObject $FinalResult -memberType NoteProperty -name “USBUsedSpace(bytes)” -value $USBUsedSpacebytes #Insert USB used space bytes size

Add-Member -inputObject $FinalResult -memberType NoteProperty -name “FileExist” -value $file #Insert file exist result

$OutPut += $FinalResult

$FinalResult | ft -autosize #Show script progression

}

$OutPut | Export-Csv -noTypeInformation -path C:\Result.csv

$OutPut | Out-GridView -Title “Result” #GUI View

By Ricky Gao (高俊) on July 27, 2014 | Scripts, Tech | A comment?

AD
ADFS
ADRMS
Android
Azure
Certification
Citrix
Cluster