Wednesday, September 10, 2014

How to check the model for a list of Dell PC with service tag

I have a need to check the model of list of PC. The only information I have is their service tag.

It may take desktop engineers a long time to check one by one if they do not have this record correctly.

I have written an auto-it script which basically do the following.

1. Load the list of the service tag from "c:\temp\tag.lst" into an array

2. For each service tag, do the following

a. Open up the Dell Service tag website (http://www.dell.com/support/home/us/en/19/product-support/servicetag/<your service tag>/diagnose?s=BSD) 

b. Download the file and search for the string "supportproductselected"

c. Extract the string in between "supportproductselect" and "/>"

3. Export the results into c:\temp\tagresult.txt

You need to install Auto-it before you can run this script and you need to put all your service tag into a text file "tag.lst" which has one service tag per line.

Here's the detail script for your reference.

-------------------tag.au3------------------------------

#include <String.au3>
#include <array.au3>
#include <IE.au3>
#include <file.au3>


Local Const $sFilePath = "c:\temp\Tagresult.txt"

    ; Create a temporary file to read data from.
    If Not _FileCreate($sFilePath) Then Return MsgBox($MB_SYSTEMMODAL, "", "An error occurred whilst writing the result file.")

   $fresult = FileOpen($sFilePath, $FO_APPEND)
      If $fresult = -1 Then
        MsgBox($MB_SYSTEMMODAL, "", "An error occurred when reading the result file.")
        Return False
    EndIf



$list = FileReadToArray("c:\temp\tag.lst")

 If @error Then
        MsgBox($MB_SYSTEMMODAL, "", "There was an error reading the file. @error: " & @error) ; An error occurred reading the current script file.
    Else
        For $i = 0 To UBound($list) - 1 ; Loop through the array.
            FileWriteLine($fresult, $list[$i] & "," & tag($list[$i]))
        Next
    EndIf

Fileclose($fresult)

func tag($word)

   $oIE = Inetget("http://www.dell.com/support/home/us/en/19/product-support/servicetag/" & $word & "/diagnose?s=BSD", "c:\temp\tag.txt")


   $f = fileopen("c:\temp\tag.txt",0)

   $con = fileread($f)
   fileclose($f)


$s = stringinstr($con, "supportproductselected")
$t = stringInstr($con, "content=", 0,1, stringinstr($con, "supportproductselected"))

$product = stringmid($con, $t+8, stringinstr($con, "/>", 0,1, $t)-$t-8)

consolewrite (chr(34) & $word & chr(34) & ", " & $product &@CRLF)

   return $product
EndFunc





------------------------------------------------------------

Wednesday, August 13, 2014

How to convert GroupPolicy backup file into HTML format without access to the original AD

I am working on a Active Directory migration project and there is a need to review all group policies in the legacy domain where we do not have the local admin right yet.

The administrator from the legacy domain only provided us the GPO backup file which is difficult to read.

Here's a simple script to convert that file into HTML format so that you could read each GPO one by one in your favourite browser.

------QueryBackupLocation2.wsf----------------


////////////////////////////////////////////////////////////////////////////
// Copyright (c) Microsoft Corporation.  All rights reserved
//
// Title: QueryBackupLocation2.wsf
// Author: mtreit@microsoft.com
// Created: 1/7/2002
//
// Purpose: Takes a GPO backup location and prints information about
// all GPOs backed up there.
////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////
// Initialization
///////////////////////////////////////
<job>

// Include necessary libraries
<script language="JScript" src="Lib_CommonGPMCFunctions.js"/>

<script language="JScript">

// Create global objects for use by the rest of the script
var GPM = new ActiveXObject("GPMgmt.GPM");
var Constants = GPM.GetConstants();

///////////////////////////////////////
// Main script
///////////////////////////////////////

// Handle command line arguments
var ArgumentList = ProcessCommandLineArguments(WScript.Arguments);
var szBackupFolder = ArgumentList.Item("BackupFolder");
var bVerbose = ArgumentList.Item("Verbose");

PrintBackupLocationData(szBackupFolder, bVerbose);

///////////////////////////////////////
// Function Definitions
///////////////////////////////////////

// Takes a file system location and prints the backups in that location
function PrintBackupLocationData(szBackupLocation, bVerbose)
{
// Get a GPMBackupDir object representing the specified backup folder
try
{
var GPMBackupDir = GPM.GetBackupDir(szBackupLocation);
}
catch (err)
{
WScript.Echo("Could not get a list of backups in folder " + szBackupLocation + ".");
WScript.Echo(ErrCode(err.number) + " - " + err.description);
return;
}

// Create a search criteria object. 
//In this case we will use a blank criteria object to return all backups.
var GPMSearchCriteria = GPM.CreateSearchCriteria();

// Get a list of all backups in the folder
try
{
var Backups = GPMBackupDir.SearchBackups(GPMSearchCriteria);
}
catch (err)
{
WScript.Echo("Error querying for backups in folder '" + szBackupLocation + "'");
WScript.Echo(ErrCode(err.number) + " - " + err.description);
return;
}

// Check if no backups were found
if (Backups.Count == 0)
{
WScript.Echo("No backups found at " + szBackupLocation);
return;
}

// Build a list of all GPOs backed up in the specified folder
var e = new Enumerator(Backups);
var Backup;
var arrGPOIDs = new Array();
var arrOutputStrings = new Array();

for (;!e.atEnd();e.moveNext())
{
Backup = e.item();

if (! ElementExists(arrGPOIDs, Backup.GPOID))
{
arrGPOIDs = arrGPOIDs.concat(Backup.GPOID);
arrOutputStrings = arrOutputStrings.concat(Backup.GPOID + "  -  " + Backup.GPODisplayName);

}

}

// Now we have a list of all GPOs backed up in the backup folder
// Print out the list
WScript.Echo("\nThe following GPOs are backed up at " + szBackupLocation + ":");
WScript.Echo("\n-- Summary --");
e = new Enumerator(arrOutputStrings);
for (; !e.atEnd(); e.moveNext())
{
WScript.Echo("  " + e.item());
}

if (bVerbose == true)
{
e = new Enumerator(arrGPOIDs);
WScript.Echo("\n\n-- Details --");
for (; !e.atEnd(); e.moveNext())
{
PrintGPOBackupData(e.item(), GPMBackupDir);
}
}
}

// Takes a backup location and a GPO GUID and prints info for all backups
// for that GPO
function PrintGPOBackupData(GPOID, BackupDir)
{
var GPMSearchCriteria = GPM.CreateSearchCriteria();
GPMSearchCriteria.Add(Constants.SearchPropertyGPOID, Constants.SearchOpEquals, GPOID);

var GPMResult;

// Get a list of all backups in the folder
var Backups = BackupDir.SearchBackups(GPMSearchCriteria);

WScript.Echo("\n------------------------------------------------------------");
//WScript.Echo("\n== Backups for GPO '" + Backups.Item(1).GPODisplayName +"' " + GPOID + " ==");
WScript.Echo("GPO Name:\t" + Backups.Item(1).GPODisplayName);
WScript.Echo("GPO ID:\t\t" + GPOID + "\n");
WScript.Echo("  " + Backups.Count + " backup(s)\n");

var e = new Enumerator(Backups);
var Backup;
for (; ! e.atEnd(); e.moveNext())
{
Backup = e.item();
WScript.Echo("  BackupID:\t" + Backup.ID);
WScript.Echo("  Timestamp:\t" + Backup.TimeStamp);
WScript.Echo("  Comment:\t" + Backup.Comment + "\n");
Backup.GenerateReportToFile(1, "c:\\temp\\gpo\\" + Backup.GPODisplayName + ".html");
}

WScript.Echo("------------------------------------------------------------\n");
}


// Check if an element already exists in an array
function ElementExists(array, value)
{
var e = new Enumerator(array);
for (; !e.atEnd(); e.moveNext())
{
if (e.item() == value)
{
return true;
}

}

return false;
}

// Takes a WScript.Arguments object and returns a dictionary object
// containing the named arguments and values that were passed in
//
function ProcessCommandLineArguments(Arguments)
{
var szBackupFolder = "";
var bVerbose = true;

// Check if this is cscript. If not, print an error and bail out
if (WScript.FullName.toLowerCase().search("wscript") > 0)
{
WScript.Echo("You must use cscript.exe to execute this script.");
WScript.Quit();
}

if (Arguments.Length == 0)
{
Arguments.ShowUsage();
WScript.Quit();
}

var Result = new ActiveXObject("Scripting.Dictionary");

szBackupFolder = Arguments(0);

if (Arguments.Named.Exists("Verbose"))
{
bVerbose = true;
}

Result.add("BackupFolder", szBackupFolder);
Result.add("Verbose", bVerbose);

return Result;
}

</script>

<!-- Usage and command line argument information -->
<runtime>

<description>
Takes a file system location and prints information about all GPOs backed-up at that location.
</description>

<unnamed name="BackupFolder" helpstring="The file system location to query" type="string" required="true" />
<named name="Verbose" helpstring="Display detailed information about each backup" type="simple" required="false" />

<example>
Example: QueryBackupLocation.wsf \\MyServer\GPOBackups
</example>

</runtime>

</job>

----

This script is using the QueryBackuplocation.wsf from Microsoft and just add one line in the file. This line will create the html file for each policies with the displayname as the file name. You will be able to look at each GPO one by one using this script.

Backup.GenerateReportToFile(1, "c:\\temp\\gpo\\" + Backup.GPODisplayName + ".html");


The prerequisite for this script to work is to install the GPMC in your windows 7 machine and you also need to have the Lib_CommonGPMCFunctions.js in the same directory as your script. You can get this js file by downloading the GPMC sample script from Microsoft

Cheers

Philip

Monday, June 30, 2014

Extract quoted data from a text file using dos batch script

In some cases,  you may need to remove the quote that contains the value you want to extract. Here's the small piece of script I used to "clean up" the value.

--start of script ---
:DeQuote
for /f "delims=" %%A in ('echo %%%1%%') do set %1=%%~A
goto :eof
---end of script----

Usage:
Call :DeQuote <variable name>

Here's an example. 

------------value.txt-------------
"Gas"
"Labels"
"Schedule"
"Location"
"Options"
---------end of value.txt----------

Here's the script to clean up the files

-------------start of script-------------

SETLOCAL EnableDelayedExpansion

del /q out.txt

for /f %%i in (value.txt) do (
set tee=%%i
call :DeQuote tee
echo !tee! >> out.txt)

goto :eof

:DeQuote
for /f "delims=" %%A in ('echo %%%1%%') do set %1=%%~A
echo %1
goto :eof

----------end of script-----------------

You will be able to get out.txt as below

------out.txt--------------
Gas 
Labels 
Schedule 
Location 
Options 
---------------------------

Tuesday, July 9, 2013

Qvod Cache !mv files to rmvb ( Qvod快播(安卓)下载文件(!mv)合并方法)

If you have been using Andriod Qvod player, you will be a little bit frustrated if you want to move the downloaded file from your phone to a computer or other media player.

Qvod is a very fantastic application in Andriod which allows you to download Peer to Peer files very easily.

While there are a lot of Qvod cacher conversion program in the internet, you do not know if they are malware or contains virus.

I written this simple batch file in dos format, the key thing it is doing is to extract the number in the middle of the cache file name, expand that with leading zeros so that the system can sort the file names accordingly.

-----------Start of qvod.bat--------------
ren *.!mv *.

for /f "tokens=1,2 delims=_ " %%i in ('dir/b') do (


setlocal ENABLEDELAYEDEXPANSION


set ttt=000000000%%j
set ttt=!ttt:~-5!
ren %%i_%%j !ttt!.rmv
endlocal

)
)

setlocal ENABLEDELAYEDEXPANSION
set tttt=copy/b
for /f %%u in ('dir/b *.rmv') do (
set tttt=!tttt! %%u +
)

%tttt:~0,-1% result.rmvb

endlocal
-----------End of qvod.bat--------------

View PowerCli Script: Automate linked clone master (base image) OS update and recompose

I believe this is one of the nightmare of View Administrators. When you have a lot of View Pool, the effort to maintain the master image is going to be tough.

While you can use ThinApp to simplify the application management, there are some occassion you cannot use ThinApp, you may have to manually update OS patches or application in the master image and do recompose to keep your link clone updated.

This process is tedious and I have two scripts to automate the OS patches update.
  1. Script to trigger Windows Update automatically on all master (or base image) that need update.
  2. Script to create a new snapshot, delete the old snapshots except the last snapshot and trigger recompose of the link clone pool.
The first script should be run first and let it run for a few hours to ensure all installation and reboot are completed before we go to step 2 to generate snapshot and link clone.

Script to trigger Windows Update automatically on all master (or base image) that need update.

The first script (OSupdate.ps1) is create to run the windows update script on all VM required.

Please visit my previous post and save that files (update.bat and wua.vbs) in the same directory as OSupdate.ps1

Prerequisite

To run the OSupdate.ps1 script, we have the following assumption.
  • All VM to be updated by the script has the same username and password with local administrator right. If there are a few different username/password, you could group those VMs with same username/password.
  • During the creation of those master image, the Windows update agent should be updated to at least 7.4.7600.226 and XP should be at least SP3.
  • All VMs should be able to access Windows Update server in Internet or the agent should be configured to pointing to any internal WSUS server.
  • All VMs are in the same folder
Basically, this script will be go through all VM in the folder specified, copy the update.bat and wua.vbs to c:\ and then run the update.bat. If the VM is powered off, it will be powered on by the script automatically.

Since the windows update are different every month, it may take a very long time for your script to download and install all patches, therefore, please make sure you have enough time to run this before you do the link clone recompose.

Here's the OSupdate.ps1 script, there are a few parameters here..
  1. Vcenter - that's the Vcenter address
  2. Folder - that's the folder contains all VMs to be updated.
  3. Admin - That's the username with local admin right on the VM operating system.
  4. Password - That's the password of the account with local admin right on the VM operating system. 
Usage:

./OSupdate.ps1 -vcenter VCENTER.DOMAIN.COM -folder "VMFolders" -admin Administrator -password Password


------------Start of OSupdate.ps1--------------

param ($vcenter, $folder, $admin, $password)

connect-viserver -server $vcenter
$VM = Get-Folder $folder | Get-VM

foreach ($v in $VM) {

if ($v.powerstate -eq "PoweredOff") {
start-VM -VM $v
start-sleep -s 180

}

Copy-VMGuestFile -Source update.bat -Destination c:\ -VM $v -LocalToGuest -GuestUser $admin -GuestPassword $password

Copy-VMGuestFile -Source wua.vbs -Destination c:\ -VM $v -LocalToGuest -GuestUser $admin -GuestPassword $password

Invoke-VMScript "c:\update.bat" -vm $v -GuestUser $admin -GuestPassword $password -ScriptType "bat"

}

--------------End of OSupdate.ps1--------------


 Script to recompose Link clone pool

The second script is to recompose the link clone pool.

Here's the parameter of the script
  1. pool_id - the ID of the link clone pool
  2. parentvm - the name of the VM of the master image
  3. delay - the number of minutes delay you wants the recompose to happen (this allows you to run this script for all VMs at the same time but the actual recompose can happens at different time to avoid IOPS storm)
  4. vcenteraddy - the full address of the Vcenter
  5. folder - the VM folder name of the master image

Usage:

./recompose.ps1 -pool_id "VM1" -vcenter VCENTER.DOMAIN.COM -folder "VMFolders" -parentvm "VMDesktop" -delay 10


------------Start of recompose.ps1-------------


param ($pool_id, $parentvm, $delay, $vcenteraddy, $folder) 

#User set variables

#Connect to vcenter and set some other variables
Connect-VIServer $vcenteraddy
Get-Datacenter | set-Variable -name datacenter

write-host $datacenter
$VM = Get-Folder $folder | Get-VM -Name $parentvm

$p = $parentvm
$Snap = Get-Snapshot -VM $VM -WarningAction SilentlyContinue | Sort-Object Created
$count = 0
foreach ($s in $Snap){
$count = $count + 1
Write-host $count
Write-host $s.name
}


foreach ($s in $Snap){
if ($count -gt 1) {
$k = " Removing " + $s.name
Write-host $k
Write-host $count
Remove-Snapshot -Snapshot $s -confirm:$false

}
$count = $count - 1
Write-Host $count

}

$p = get-date.Year + get-date.Month + get-date.Day + get-date.Hour + get-date.minute + get-date.second

Write-Host $p
Get-VM $VM | New-Snapshot -Name $p
Write-Host "New Snapshot created"


$snapshots = Get-Snapshot -VM $VM -WarningAction SilentlyContinue | select VM, Name, @{Name="Age";Expression={((Get-Date)-$_.Created).Hours}} | Sort-Object Age
$parentsnapshotpath = ""
foreach ($s in $snapshots){
$parentsnapshotpath = "/" + $s.Name + $parentsnapshotpath
}
write-host $parentsnapshotpath

get-composerdomain | Get-DesktopVM -pool_id $pool_id | Send-LinkedCloneRecompose -schedule ((Get-Date).AddMinutes($delay)) -parentvmpath /$datacenter/vm/$folder/$parentvm -parentsnapshotpath $parentsnapshotpath -forceLogoff:$true -stopOnError:$true

update-automaticlinkedclonepool -pool_id $pool_id -parentSnapshotPath $parentsnapshotpath
Write-Host "Pool recomposed sucessfully."


-------------End of Recompose.ps1-------------


Here's some of my reference
http://terenceluk.blogspot.hk/2012/03/updating-a-vmware-view-50-automatic.html

Tuesday, July 2, 2013

View 5.1 PowerCLI powershell script to automate the Link Clone creation

Here's a script we used to create hundred of VMWare View link clone pool for our VDI project. While the user interface of View Administrator is very good for creating link clone, it becomes a nightmare when you need to create 100+ VM pools

This script basically do the following:-

  1. Remove all old the snapshot of the Base Image except the latest snapshot
  2. Create a new snapshot on the Base Image for the link clone. The name of the snapshot is the current date and time.
  3. Create a new link clone pool using the latest snapshot (just created) using the following name as parameters
    • $cluster - Cluster
    • $pool_id - Pool ID 
    • $displayname - Display Name
    • $datastore - The Datastore for storing the Link Clone
    • $minimumcount - Minimum number of VMs
    • $maximumcount - Maximum number of VMs
    • $vcenteraddy - The full path of the Vcenter Server
    • $folder - the folder of the base image (we use the same location to keep the Link clone folder)
    • $ou - the Organizational unit in the Active Directory
    • $entitlementName - the group name in Active Directory that are entitled to this group
    • $parentvm - the VM name of the base image
  4. There are a few policy has been set by default and you could modify that in the first section of the script.
    • $headroomCount = 2 
    • $refreshpolicytype = "Never"
    • $deletepolicy = "DeleteOnUse" 
    • $powerpolicy = "AlwaysOn" 
    • $autologofftime = 540 
    • $IsUserResetAllowed = $true
    • $nameprefix = $pool_id + "{n:fixed=2}"
  5. Pre-requisite for this script to work for you
    • You are happy to have the LC folders under the same folder of your Base Image are contained.
    • All base image should be turned off and do ipconfig /release before doing so.
    • You should have planned all the parameters e.g datastore, clusters,...etc on a spreadsheet for all the pools, then you can use a simple formula in Excel to create the script.
  6. Here's an example of using this script (assume this script is saved as LC.ps1)
./LC.ps1 -cluster "ClusterA" -pool_id "VMD-1" -displayname "VM testing pool 1" -datastore "Datastore1" -minimumcount 2 -maximumcount 5 -vcenteraddy "vcenter.server.com" -folder "Pilot" -OU "OU=VDI" -entitlementName "VMUsers Group" -parentvm "VMDesktop"


Here's the detail of the script. Enjoy!!!

------Start of the scripts--------



param ($cluster, $pool_id, $displayname, $datastore, $minimumcount, $maximumcount, $vcenteraddy, $folder, $OU, $entitlementName, $parentvm)  




#Connect to vcenter and set some other variables
Connect-VIServer $vcenteraddy
Get-Datacenter | set-Variable -name datacenter

$headroomCount = 2 
$refreshpolicytype = "Never" 
$deletepolicy = "DeleteOnUse" 
$powerpolicy = "AlwaysOn" 
$autologofftime = 540 
$IsUserResetAllowed = $true 
$nameprefix = $pool_id + "{n:fixed=2}"

set-variable -name vmfolderpath -value /$datacenter/vm/$folder


$VM = Get-Folder $folder | Get-VM -Name $parentvm

$p = get-date.Year + get-date.Month + get-date.Day + get-date.Hour + get-date.minute + get-date.second 

Get-Snapshot -VM $VM -WarningAction SilentlyContinue | select Id, Created | Sort-Object Created -descending
$Snap = Get-Snapshot -VM $VM -WarningAction SilentlyContinue | Sort-Object Created -descending

$count = 0

foreach ($s in $Snap){

if ($count -gt 0) {

Write-host "Removing Snapshot"
Remove-Snapshot -Snapshot $s -confirm:$false

}
$count = $count - 1
Write-Host $count


}

Write-Host $p
Get-VM $VM | New-Snapshot -Name $p
Write-Host "New Snapshot created"


$snapshots = Get-Snapshot -VM $VM -WarningAction SilentlyContinue | select VM, Name, @{Name="Age";Expression={((Get-Date)-$_.Created).Hours}} | Sort-Object Age 

$parentsnapshotpath = ""

foreach ($s in $snapshots){

$parentsnapshotpath = "/" + $s.Name + $parentsnapshotpath

}

write-host $parentsnapshotpath




get-composerdomain | add-automaticlinkedclonepool -pool_id $pool_id -displayname $displayname -nameprefix $nameprefix -vmfolderpath $vmfolderpath -parentvmpath /$datacenter/vm/$folder/$parentvm -resourcepoolpath /$datacenter/host/$cluster/Resources -parentsnapshotpath $parentsnapshotpath -datastorespecs "[Conservative,OS,data]/$datacenter/host/$cluster/$datastore" -persistence Nonpersistent -organizationalUnit $OU -minimumcount $minimumcount -maximumcount $maximumcount -headroomCount $headroomCount -refreshpolicytype $refreshpolicytype -deletepolicy $deletepolicy -powerpolicy $powerpolicy -autologofftime $autologofftime -IsUserResetAllowed $IsUserResetAllowed 

Write-Host "Pool created sucessfully.  Now I will entitle it."

#Add-PoolEntitlement 
$entitlement =  Get-User -name $entitlementName 

Get-Pool -pool_id $pool_id | Add-PoolEntitlement -sid $entitlement.sid

Write-Host "Entitled and building VMs."

Write-Host "THE END"

---------end of the script-----------

Friday, June 28, 2013

Vsphere PowerShell Script (1) - Update Network Adapter

This is a powershell script that help you to update the Network Adapter for the virtual machine in ESXi.

You can save this moveNet.ps1 and you will need to login to the ESXi server or your Vcenter before you can run this script.

The script basically help you to update the NetworkAdapter attribute of the Virtual machine using the Set-NetworkAdapter function.

In order to ensure the virtual machine get a new ip address after the network is changed, we put in some check to determine if the machine is powered on. If that's online, we will do ipconfig /release before updating the networkadapter and do an ipconfig /renew after that.

To use this script, in the PowerCli windows, after you connect to your ESXi or VCenter, you should run

./moveNet.ps1 -vmname VM123 -newnetwork VLAN1 -administrator Administrator -password password

Please refer to the detail and modify that to suit your environment!!

----start of moveNet.ps1-----

Param($vmname, $newnetwork, $administrator, $password)

$VM = Get-VM -Name $vmname
if ($vm.powerstate -eq "PoweredOff") {
Get-VM -Name $vmname | Get-NetworkAdapter | Set-NetworkAdapter -NetworkName $newnetwork -confirm:$false
}

if ($vm.powerstate -eq "PoweredOn") {
Invoke-VMScript "ipconfig /release" -vm $VM -GuestUser $administrator -GuestPassword $password -ScriptType "bat"
Get-VM -Name $vmname | Get-NetworkAdapter | Set-NetworkAdapter -NetworkName $newnetwork -confirm:$false
Invoke-VMScript "ipconfig /renew" -vm $VM -GuestUser $administrator -GuestPassword $password -ScriptType "bat"
}

-----end of script-----

Script to force install all windows update or patches

I would like to post the script I used to update the base image for my VDI project for Windows XP, Vista or Windows.

Prerequisite:

1. You need to have Windows XP SP3 or above and installed at least the Windows update agent  7.4.7600.226
http://support.microsoft.com/kb/946928

2. You need to create the following files
  • wua.vbs
  • update.bat
The wua.vbs is modified from the microsoft wua.vbs script that contact the Windows update website to download upgrade. This script has been updated to download all patches and skipped all the prompt to save time.

Update.bat simply ensure the Windows update service is enabled before running wua.vbs.


Here's the detail of the script. Please make sure you put these two scripts in the same directory before you run it.

a. wua.vbs


This is actually a vbscript from Microsoft which use the Windows update agent to get the update.

Set updateSession = CreateObject("Microsoft.Update.Session")
updateSession.ClientApplicationID = "MSDN Sample Script"

Set updateSearcher = updateSession.CreateUpdateSearcher()
WScript.Echo "Searching for updates..." & vbCRLF
Set searchResult = _
updateSearcher.Search("IsInstalled=0 and Type='Software' and IsHidden=0")

WScript.Echo "List of applicable items on the machine:"
For I = 0 To searchResult.Updates.Count-1
    Set update = searchResult.Updates.Item(I)
    WScript.Echo I + 1 & "> " & update.Title
Next

If searchResult.Updates.Count = 0 Then
    WScript.Echo "There are no applicable updates."
    WScript.Quit
End If

WScript.Echo vbCRLF & "Creating collection of updates to download:"
Set updatesToDownload = CreateObject("Microsoft.Update.UpdateColl")
For I = 0 to searchResult.Updates.Count-1
    Set update = searchResult.Updates.Item(I)
    addThisUpdate = false
    If update.InstallationBehavior.CanRequestUserInput = true Then
        WScript.Echo I + 1 & "> skipping: " & update.Title & _
        " because it requires user input"
    Else
        If update.EulaAccepted = false Then
            WScript.Echo I + 1 & "> note: " & update.Title & _
            " has a license agreement that must be accepted:"
            WScript.Echo update.EulaText
            WScript.Echo "Do you accept this license agreement? (Y/N)"
                update.AcceptEula()
                addThisUpdate = true
           Else
            addThisUpdate = true
        End If
    End If
    If addThisUpdate = true Then
        WScript.Echo I + 1 & "> adding: " & update.Title
        updatesToDownload.Add(update)
    End If
Next

If updatesToDownload.Count = 0 Then
    WScript.Echo "All applicable updates were skipped."
    WScript.Quit
End If
   
WScript.Echo vbCRLF & "Downloading updates..."

Set downloader = updateSession.CreateUpdateDownloader()
downloader.Updates = updatesToDownload
downloader.Download()

Set updatesToInstall = CreateObject("Microsoft.Update.UpdateColl")
rebootMayBeRequired = false
WScript.Echo vbCRLF & "Successfully downloaded updates:"
For I = 0 To searchResult.Updates.Count-1
    set update = searchResult.Updates.Item(I)
    If update.IsDownloaded = true Then
        WScript.Echo I + 1 & "> " & update.Title
        updatesToInstall.Add(update)
        If update.InstallationBehavior.RebootBehavior > 0 Then
            rebootMayBeRequired = true
        End If
    End If
Next

If updatesToInstall.Count = 0 Then
    WScript.Echo "No updates were successfully downloaded."
    WScript.Quit
End If

If rebootMayBeRequired = true Then
    WScript.Echo vbCRLF & "These updates may require a reboot."
End If

WScript.Echo  vbCRLF & "Would you like to install updates now? (Y/N)"
strInput = "y"
WScript.Echo

If (strInput = "Y" or strInput = "y") Then
    WScript.Echo "Installing updates..."
    Set installer = updateSession.CreateUpdateInstaller()
    installer.Updates = updatesToInstall
    Set installationResult = installer.Install()

    'Output results of install
    WScript.Echo "Installation Result: " & _
    installationResult.ResultCode
    WScript.Echo "Reboot Required: " & _
    installationResult.RebootRequired & vbCRLF
    WScript.Echo "Listing of updates installed " & _
    "and individual installation results:"

    For I = 0 to updatesToInstall.Count - 1
        WScript.Echo I + 1 & "> " & _
        updatesToInstall.Item(i).Title & _
        ": " & installationResult.GetUpdateResult(i).ResultCode
    Next
End If

b. update.bat

sc config wuauserv start= demand
sc start wuauserv
cscript  wua.vbs


Monday, August 27, 2012

Automated script to check the services in Automatic and Manual Mode

This week I am working on some new requirement from our Active Directory Architect to provide all the services required to start as "Automatic" and "Manual" for all my VMWare VDI infrastructure servers.

It is very painful to go to each server one by one to do this, so I written a simple Powershell script to check.

You will need to prepare for a text file (Servers.txt) which list all your servers you want to check. (One hostname in each line). This Servers.txt file should be in the same location as your service.ps1 script.

---start of service.ps1 script----------------------
$compArray = get-content .\Servers.txt
foreach($strComputer in $compArray)
{
echo $strComputer
echo --------------------------------------------------------------------------------------------------
Get-WmiObject Win32_Service -ComputerName $strComputer | Where {$_.StartMode -like "*Auto*"}| select-object DisplayName,Name,StartMode,StartName
echo --------------------------------------------------------------------------------------------------
Get-WmiObject Win32_Service -ComputerName $strComputer | Where {$_.StartMode -like "*Manual*"}| select-object DisplayName,Name,StartMode,StartName
echo --------------------------------------------------------------------------------------------------

}

---end of service.ps1 script----------------------

To run that script, you just need to login with an account with Local Administrator right for all servers needed and run the following command in the Powershell

.\services.ps1 | out-file results.txt

You will then see all services in results.txt. 

Wednesday, February 23, 2011

How to monitor free space of a group of desktop

If you have some special group of desktop shared by a team, you may have the similar issue as me that the hard disk space used up quickly simply because of the temp file (like the ost file of outlook).

I have written a script to monitor the freespace of a few machines...

First of all, I create a freespace.bat file like this

----start of freespace.bat-----



@echo off
for /f "usebackq delims== tokens=2" %%x in (`wmic /node:%1 logicaldisk where "DeviceID='C:'" get FreeSpace /format:value`) do (set  tx1234=%%x)


for /f "usebackq delims== tokens=2" %%x in (`wmic /node:%1 logicaldisk where "DeviceID='C:'" get Size /format:value`) do (set  txsi=%%x)


echo %1;%tx1234%;%txsi%


----end of freespace.bat-----


This script basically will poll the PC that you specified provide the freespace and the disksize of c-drive.

The usage is like this

freespace.bat <hostname>


If you have a list of machines, then, you can simply put their hostname into a text file, e.g. deskfree.txt and then use the following batch file to check their freespace and echo the results into a text file.

----start of mon.bat-------

@echo off
del /q deskfree.txt
for /f %%y in (desk.txt) Do freespace %%y >> deskfree.txt

------end of mon.bat--------

Wednesday, February 9, 2011

How to install apps from Ovi-store into your Satio Phone without hacking phone


If you are the poor Satio users like me who do not have access to Ovi-store and you want to use the latest firmware (or you have to) in order to have the full WXGA video, here's the steps you could follow to install Nokia apps while continue to get the latest update from Sony Ericsson.

1) Download and extract  SISContents

2) Install Firefox in your PC and install the Add-on "User Agent Switcher"

3) Setup a new user Agent which allows you to pre-tend to be a Nokia phone. You can use the string for Nokia 5800 as below



Mozilla/5.0 (SymbianOS/9.4; U; Series60/5.0 Nokia5800d-1/10.0.008; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/413 (KHTML, like Gecko) Safari/413

4) Next, goto the Ovi-store to download all the apps you want.

5)Then Open the siscontents file extsis.exe the file you downloaded in first step..





















6) then select the sis file which you have downloaded from ovi-store















7) Now You Delete All The Signatures Present in the sis File


















 8) Now Select Sign Package And Follow The Following Steps


















9) Now a new window will pop out to sign the sis file. You need to have a certificate and key file first for your phone. if you have not done it please read my previous post of Get You s60v5 certificate and key form OPDA. If you have the certificate and key files please continue.



















10) Now After this close this window and save your new hacked sis file.















Oh.....in some case, you cannot straightly do this as the file you download from OVI-store are .dm file!!!


Some of the Ovi Store apps downloaded to PC are in DM file format. So, how to install the DM files from Ovi Store on Nokia phone?

You need to open and edit the DM file with a file editor that can deal with binary file format (i.e. hex content not ASCII). My favorite is Notepad++ (powerful open-source editor for Windows), as shown in this “silent” screencast:








  1. Open the DM file with Notepad++
     
  2. Move the cursor from top-left position to the beginning of “z” character and hit DELETE key – that will delete top 4 lines up to the blank space in front of “z” character, as shown in the YouTube video (above).
     
  3. Save and close the edited file.
     
  4. Remove the .dm file extension from file name – if the 2nd last suffix is SIS, then the converted file is in SIS file format, otherwise it is SISX file format.
  5. Then, you can use the same method above to sign the application with your own certificate!!!

Enjoy...

    Tuesday, February 1, 2011

    How to check what kind of hotfix are installed in a PC

    To check what kind hotfix has been installed, we could use a tool Pstools available from Microsoft.

    http://technet.microsoft.com/en-us/sysinternals/bb897550

    The command line is very straightforward, you simply do that by

    psinfo -h

    And then you will see something like this

    P:\Desktop\pstools>psinfo -h
    PsInfo v1.75 - Local and remote system information viewer
    Copyright (C) 2001-2007 Mark Russinovich
    Sysinternals -
    www.sysinternals.com
    System information for \\x12354
    Uptime:                    0 days 21 hours 16 minutes 53 seconds
    Kernel version:            Microsoft Windows XP, Multiprocessor Free
    Product type:              Professional
    Product version:           5.1
    Service pack:              3
    Kernel build number:       2600
    Registered organization:   Fei

    Registered owner:          Fei User
    Install date:              8/6/2010, 8:05:42 PM
    Activation status:         Error reading status
    IE version:                7.0000
    System root:               C:\WINDOWS
    Processors:                2
    Processor speed:           2.7 GHz
    Processor type:            Intel(R) Core(TM)2 Duo CPU     E7400  @
    Physical memory:           3292 MB
    Video driver:              Intel(R) 4 Series Internal Chipset

    Installed     HotFix
    10/6/2010     Microsoft Internationalized Domain Names Mitigation APIs
    10/6/2010     Microsoft National Language Support Downlevel APIs
    11/11/2010    Security Update for Windows Media Player (KB2378111)
    8/7/2010      Security Update for Windows Media Player (KB954155)
    8/7/2010      Security Update for Windows Media Player (KB968816)
    8/7/2010      Security Update for Windows Media Player (KB973540)
    1/10/2010     Security Update for Windows Media Player (KB975558)
    26/7/2010     Security Update for Windows Media Player (KB978695)
    10/6/2010     Security Update for Windows Media Player 10 (KB917734)
    8/7/2010      Security Update for Windows XP (KB941569)
    8/7/2010      Security Update for Windows Internet Explorer 7 (KB974455)
    8/6/2010      Windows XP Service Pack 3
    4/9/2010      Security Update for Windows XP (KB2079403)
    4/9/2010      Security Update for Windows XP (KB2115168)
    1/10/2010     Security Update for Windows XP (KB2121546)
    4/9/2010      Security Update for Windows XP (KB2160329)
    29/7/2010     Security Update for Windows XP (KB2229593)
    1/10/2010     Security Update for Windows XP (KB2259922)
    11/11/2010    Security Update for Windows XP (KB2279986)
    12/8/2010     Security Update for Windows XP (KB2286198)
    ......


    If you are going to feed this information to an automation script so that you can consolidate all inforamtion by yourself, you can use the script like this.

    del checkhotfix.txt /q
    del 0123894985.txt /q
    psinfo -h > 0123894985.txt
    for /f "skip=18 tokens=1*" %%i in (0123894985.txt) do @echo %%i %%j >> checkhotfix.txt


    This script will skip the first 18 lines of the information so you can easily import them into an access or SQL database for further analysis.