Script bits (update 4)

Posted by: hbr in scriptpowershellesxbashActive Directory on Print 

This post is a quick gathering of a few small scripts I wrote with my IT-life's motto: "Never do anything twice"

None of them are very special but each of them is a result of a short moment of frustration and a few minutes of gvim typing (yes, I use 'vi' on windows too).

so far this article contains:

 

  1. Add wallpapers from a lot of subdirs to a Windows 7 Theme
  2. Change everybody's manager in Active Directory
  3. Execute one command on all your ESX hosts
  4. Link recorded programs to decently defined videos in MythTV (mythvideo)

 

nr 1: Wallpaper subdirectories

I have a lot of pictures in a lot of subdirectories that I want to add to the rotating backgrounds on my Windows 7 desktop. I could add them one by one through the wizard at Control Panel\All Control Panel Items\Personalization\Desktop Background. This is of course not how I do things.

So I created a custom theme, changed directory to C:\users\[username]\Appdata\Local\Microsoft\Windows\Themes, edit the new.theme file and look for Slideshow section and change it to:

  • [Slideshow]
  • Interval=1200000
  • Shuffle=1
  • ImagesRootPath=D:\pictures\backgrounds
That should be the end of the file. Next run the next script and redirect output to the theme file like ".\addpict.cmd >> new.theme"
  • set cnt=0
  • pushd D:\pictures\backgrounds
  • for /R %%i in (*.jpg) do call :proc "%%i"
  • popd
  • goto :EOF
  • :proc
  • echo Item%cnt%Path=%~1
  • set /a cnt+=1
  • goto :EOF

and all 1800 backgrounds are rotating nicely every 20 minutes.

And that’s it. Windows Batch is pretty cool :)

nr 2: Change everybody’s manager in AD

We’re using Active Directory to store a picture and some other data from our users (see http://virtuall.eu/blog/mugshots-from-the-active-directory-127). Now we reorganized a bit and adapted the web facebook to show everybody’s manager too. Then came the tedious task of filling in everybody’s manager. Of course I refuse to (let anybody) do that with the AD Users and Computers way-too-slow wizards. So we script:

  • $rootdn=([adsi]"").distinguishedName
  • $ou=[adsi]("LDAP://ou=users,"+ $rootdn)
  • $users=$ou.psbase.children
  • $csv=import-csv users.csv
  • $users|%{
  •   $u=$_.samaccountname
  •   $m=$users|?{ $_.samaccountname -eq ($csv|?{$u -eq $_.samaccountname}).manager}
  •   if ($m) {
  •     $_.manager=$m.distinguishedname
  •     $_.setinfo()
  •     "Manager for " + $_.cn + " set to " + $m.cn
  •   } else {
  •     -join ($_.cn, " has no manager")| write-host -foregroundcolor red
  •   }
  • }

put a file ‘users.csv’ in the same directory with a format:

  • sn,sAMAccountName,Manager
  • lastname,username,manager-username
  • lastname2,username2,manager2-username

and that’s it. Powershell is pretty cool :)

nr 3: Execute command on all ESX hosts

Ever had the need to change something on all your ESX hosts using an SSH terminal? It’s a pain to repeatedly do the same thing over and over again..

Luckily you can execute remote SSH commands. For maximum effect, allow remote root access on all servers or passwordless sudo from a specific user. I know it's a security risk if you don't take other measures but there's plenty you can to do make it acceptably secure again (like allowing ssh access only from another ESX host, not from anything else).

Next, designate one server to be the command-master and put the next script in /root as ‘ExecAll’:

  • #!/bin/bash
  • Hostbase=ESXhost-
  • Maxhosts=15
  • # no need to edit below this line
  • noHecho=0
  • Fork=0
  • All=0
  • [ "$1" == "-n" ] && noHecho=1 && shift
  • [ "$1" == "-f" ] && Fork=1 && shift
  • [ "$1" == "-a" ] && All=1 && shift
  • [ "$1" == "-h" –o "$1" == "--help" ] && {
  •   echo -e "\n`basename $0` command [options]"
  •   echo -e "\n\n  \"$0 -h\" for help"
  •   echo -e "  \"$0 -n command [options]\" doesn\'t echo hostname\n"
  •   echo -e "  \"$0 -f command [options]\" forks into the background \n"
  •   exit 1
  • }
  • for i in `seq 1 1 $Maxhosts`; do
  • [ "$noHecho" == "1" ] || echo $Hostbase$i:
  • [ "$Fork" == "1" ] && ssh -f $Hostbase$i $* || ssh $Hostbase$i $*
  • done

Next, run ‘ssh-keygen –N ""’ to generate a keypair. Then execute the next command:

  • for i in `seq 1 1 15`; do scp /root/.ssh/id_rsa.pub ESXhost-$i:/root/.ssh/authorized_keys ; done

Type in the password for each host (it will be the last time you need to) and things are set. Test with:

  • /root/ExecAll ls

and that’s it. Bash is pretty cool :)

nr 4: Link recorded programs to decently defined videos in MythTV (mythvideo)

When MythTV records programs, it uses an internal naming convention that makes it very hard for humans to understand which show is which.

When you have a remote media player you would normally play videos from a share of the mythbackend. With recorded programs this is pretty useless as you have no way of knowing what program you’re starting when you share the recordings as is.

This script creates links with a descriptive name for each recording into the videos directory of MythTV. It also injects metadata into the database for mythfrontend to understand.

  • #!/bin/bash
  • . /etc/mythtv/mysql.txt
  • C=5 # nr of columns in the query resultset
  • BASE="mysql -p$DBPassword -u $DBUserName $DBName"
  • # now get the location of the default recording directory
  • REC=`$BASE -e 'select dirname from storagegroup where groupname="Default";' -B|tail -1`
  • # and get the location of the location of the video files
  • LNK=`$BASE -e 'select data from settings where value="VideoStartupDir";' -B|tail -1`/Recordings
  • # generate a list of all recorded shows
  • LST=`$BASE -e 'select basename,starttime,title,subtitle,endtime from recorded order by title;' -B`
  • [ -f $LNK/folder.jpg ] || wget http://www.localwin.com/julie/system/files/lu10/19StudioRecording_0.jpg -O $LNK/folder.jpg
  • IFS=$'\n'
  • row=0
  • # next, put all recordings in an array
  • for i in $LST; do
  •   IFS=$'\t'
  •   for j in $i; do
  •     rec[$row]=$j
  •     row=$[ row + 1 ]
  •   done
  •   # some shows have no subtitle, we compensate by copying the title
  •   if [ $[ $row % $C ] -ne 0 ]; then
  •     rec[$row]=${rec[$row-1]}
  •     rec[$row-1]=${rec[$row-2]}
  •     row=$[ row + 1 ]
  •   fi
  • done
  • # next, we loop through the array to generated a new filename with specified data
  • for ((i=$C; i<$row; i=i+$C)); do
  •   dt=`date -d "${rec[$i+1]}" +%b-%d\ %Hh%M`
  •   # calculate the length of the recording (endtime – starttime)/60
  •   len=$[ ( $( date -d "${rec[$i+4]}" +%s ) - $( date -d "${rec[$i+1]}" +%s ) ) / 60 ]
  •   if [ -f $REC${rec[$i]} ]; then
  •     mkdir -p "$LNK/${rec[$i+2]}" 2> /dev/null
  •     FN="${rec[$i+2]}/${rec[$i+3]} $dt"
  •     ln -s "$REC${rec[$i]}" "$LNK/$FN.mpg" 2> /dev/null
  •     # look for a previous record in the metadata
  •     ID=`mysql -p$DBPassword -u $DBUserName $DBName -e "select intid from videometadata where filename=\"$LNK/$FN.mpg\";"|tail -1`
  •     if [ -z $ID ]; then
  •       # if no record exists, insert a new one with proper data
  •       mysql -p$DBPassword -u $DBUserName $DBName -e "insert into videometadata (title, subtitle, plot, director, rating, inetref, homepage, year, releasedate, userrating, length, showlevel, filename, hash, coverfile, host) values ('${rec[$i+2]}', '${rec[$i+3]} $dt', '${rec[$i+3]} $dt', 'Unknown', 'NR', '00000000', '', $( date +%Y ), '0000-00-00', 0.0, $len, 1, '$LNK/$FN.mpg', '', '$REC${rec[$i]}.png', '') "
  •     else
  •       # if a record exists, update it with what we know
  •       mysql -p$DBPassword -u $DBUserName $DBName -e "update videometadata set length=$len,plot=\"${rec[$i+3]} $dt\",subtitle=\"${rec[$i+3]} $dt\",coverfile=\"$REC${rec[$i]}.png\" where intid=$ID"
  •     fi
  •     echo Added ${rec[$i+2]}/${rec[$i+3]} $dt
  •   fi
  • done
  • IFS=$'\n'
  • # next, we clean up any links that point to shows that were deleted
  • for i in `find $LNK -iname \*.mpg`; do
  •   if [ -h "$i" -a ! -r "$i" ]; then rm "$i"; fi
  • done

 

and that’s it. Bash really is pretty cool :)

Comments (0)Add Comment

Write comment
You must be logged in to post a comment. Please register if you do not have an account yet.

busy