Archive for the ‘Scripting’ Category

I have been looking at getting a script together for a while to mass change some shortcuts we have on our file server to point to a different location. After some research, and some playing around I found a really easy way to do this in Powershell:


# Call wscript com object
$shell = new-object -com wscript.shell

# Recurse through directories for .lnk files
dir "I:\" -filter *.lnk -recurse | foreach {
$lnk = $shell.createShortcut($_.fullname)
$oldPath= $lnk.targetPath

# If match text, perform operation
if($oldpath -match "\\serverold\share1")
{
write-host "Match: " + $_.fullname
remove-item $_.fullname
$lnknew = $shell.createShortcut($_.fullname)
$lnknew.targetPath = "`"\\newserver\share1`""
$lnknew.IconLocation = "%SystemRoot%\system32\SHELL32.dll,4"
$lnknew.Save()
}
}
Write-Host "End..."

From time to time our Citrix users end up with multiple sessions on our Citrix farm, especially when accessing the farm via Citrix access gateway and they loose connectivity. Most of these are fixed by setting sessions in the disconnected state to be automatically reset after 15 mins. (We allow this time  incase users are moving to a meeting room for example).

The big problem for us is that you can’t run multiple instances of Lotus Notes, so the disconnected session needs to be reset before the user can fire up Lotus Notes again, otherwise they will see an error like:

“You cannot use the Administration program while the Domino Server is running. Either shut down the Domino Server (buy keep the file server running) or choose the icon labeled ‘Lotus Notes’ instead.”

In order to try and make things a bit easier on the helpdesk, I created a script that will allow users to reset their own Citrix sessions. If you want to use it you’ll need to populate the first array with a list of all the servers in your farm, then create a shortcut:

cscript /nologo citrixreset.vbs

I’ve set mine to run minimized so that they don’t see random command windows popping up.

It should also be noted, that the script resets any disconnected sessions first, so that it can still carry on and kill the active one at the end! I know it’s not the slickest of scripts (Lots of splitting arrays and capturing command output), but I couldnt find any nice objects to do it properly with!

 citrixServers = array("CXS38", "CXS39", "CXS40", "CXS41")

Set objShell = CreateObject("WScript.Shell")

Sub resetSession(s)
    count = count + 1
    sessionID = trim(mid(s,48,5))
    citrixServer = trim(mid(s,1,6))
    wscript.echo "RESET SESSION " & sessionID & " /SERVER:" & citrixServer
    Set oExec = objShell.Exec("RESET SESSION " & sessionID & " /SERVER:" & citrixServer)
End Sub

userName = objShell.ExpandEnvironmentStrings("%UserName%")

For Each citrixServer In citrixServers

    wscript.echo "QUERY SESSION " & userName & " /SERVER:" & citrixServer
    Set oExec = objShell.Exec("QUERY SESSION " & userName & " /SERVER:" & citrixServer)

    Do While oExec.Status = 0
        WScript.Sleep 100
    Loop

    Do While oExec.StdOut.AtEndOfStream <> True
        sessionOutput = sessionOutput & vbCrLf & citrixServer & oExec.StdOut.ReadLine
    Loop

Next

count = 0
sessions = split(sessionOutput, vbCrLf)
wscript.echo

For Each session In sessions
    if InStr(session, "wdica") and InStr(session, "Disc") then wscript.echo session
Next

For Each session In sessions
    if InStr(session, "wdica") and InStr(session, "Active") then wscript.echo session
Next

For Each session In sessions
    if InStr(session, "wdica") and InStr(session, "Disc") then resetSession(session)
Next

For Each session In sessions
    if InStr(session, "wdica") and InStr(session, "Active") then resetSession(session)
Next

msgbox "Reset " & count & " Citrix session(s) for " & userName

Shadow copies are a brilliant time-saver… I can recover a deleted/overwritten/corruped file in a matter of seconds – or better still, the end user can do it! We currently have a schedule that takes a snapshot of our main fileserver at 7am and noon. While this is quite good, it quickly eats up diskspace, then all the snapshots get ditched and we have to start collecting them again. I wished there was some more complex scheduling and management for the shadows - I would find it far more useful to have more of the recent snapshots, and less of the older ones. Unfortunatly there’s no inbuilt functionality to do this, so I thought it was time to write a script…

I put together the following, it looks through all the snapshots on the system, and will delete those that match the following criteria:

- Older than 3 days and created after 7am
- Older than 7 days and not created on a Monday
- Older than 31 days

Scheduled to run daily, it should work a treat. The amount of snapshots should also stay constant, as once they are older then 31 days they will be removed.

  option explicit

  Dim objWMI, snapshots, snapshot, sDate, vDate, deleteSnapshot

  Set objWMI = GetObject("winmgmts://localhost/root/cimv2")
  Set snapshots = objWMI.ExecQuery("select * from Win32_ShadowCopy")
  set sDate = CreateObject("WbemScripting.SWbemDateTime")

  WScript.echo "Searching for all snapshots..."

  for each snapshot in snapshots

      sDate.Value = snapshot.InstallDate
      vDate = sDate.GetVarDate(True)
    
      WScript.echo vbCrLf & "Found snapshot... Created " & vDate
      'WScript.echo snapshot.VolumeName

      if (DateDiff("d", vDate, Date) > 7) then
          if (DatePart("w", vDate) <> 2) then
              WScript.echo "Older than 7 days & Not created on a Monday"
              deleteSnapshot = true
          end if
      end if

      if (DateDiff("d", vDate, Date) > 3) then
          if (hour(vDate) > 7) then
              WScript.Echo "Older than 3 days & Created after 7AM"
              deleteSnapshot = true
          end if
      end if

      if (DateDiff("d", vDate, Date) > 31) then
          WScript.Echo "Older than 31 days"
          deleteSnapshot = true
      end if

      if (deleteSnapshot) then
          WScript.echo "*** Deleting snapshot ***"
          snapshot.Delete_()
          deleteSnapshot = false
      else
          WScript.echo "*** Keeping snapshot ***"
      end if

  next

You’ll sometimes have a server that has loads of scheduled tasks that need to run as a specific user account, and sometimes you might need to update the account they run as, or reset the password.

I recently had to change loads of these on our Altiris server, and didn’t really fancy doing it by hand! The following script will update the runas user/password for all scheduled tasks on your system…

@echo off

set Password=password
set Username=DOMAIN\username

cd /d "%SystemRoot%\tasks
for %%a in (*.job) do call :ChangePW %%a
goto :eof

:ChangePW
set TaskName=%*
set TaskName=%TaskName:~0,-4%
SCHTASKS /Change /RU %Username% /RP %password% /TN "%TaskName%"

Massive JPEGs

May 15th, 2008 4 Comments

I really hate it how digital cameras now create files that are stupidly big, every photo that I use - and most of those that others use only ever stay on the screen. So why do we need them saved at 5120×3825 eating about 4Mb each?!

In a large multi-user environment these massive images quickly eat up alot of disk space. I figured you could save alot of disk space by automatically resizing the images down if they are bigger than a certain size, so I got cracking on a VBScript to do this for me. Read the rest of this entry »