Showing posts with label hth. Show all posts
Showing posts with label hth. Show all posts

Monday, June 21, 2010

Exporting MongoDb with Powershell

I'm just going to leave this right here. This fixes up the output from mongoexport to create an array, suitable for XMLSpy...

function Export-Wmi
{
 Param (
  [Parameter(mandatory=$true)]
  [string]
  $DbName,
  
  [Parameter(mandatory=$true)]
  [array]
  $CollectionNames
 )
 
 Process {
  $CollectionNames |
  foreach {
   $output = ""
   $cmd = ""
   $docs = C:\Path\To\Mongo\bin\mongoexport.exe `
    --db $DbName `
    --collection $_ `
    2>$null
   
   $output += "["
   $bfirst = $true
   foreach( $doc in $docs )
   { 
    if( -not $bfirst )
    {
     $output += ","
    }
    
    $output += $doc
    
    $bfirst = $false
   }
   
   $output += "]"
   
   $output | Out-File -FilePath "C:\Path\To\Data\$_.json"  
  }
 }
}

Export-Wmi -DbName "reports" -CollectionNames @("coll1", "coll2" )

Wednesday, June 2, 2010

Powershell, MongoDB, and WMI

I had reason to write a short cmdlet which converts WMI objects to MongoDB docs. It ain't much, but it works so far:

 [Cmdlet( VerbsData.ConvertTo, "MongoDoc" )]
 public class ConvertToMongoDoc : Cmdlet
 {
  [Parameter( Mandatory = true, ValueFromPipeline = true )]
  public PSObject InputObject { set; get; }

  protected override void ProcessRecord()
  {
   Document converted = (Document)WmiConvert( InputObject.BaseObject );
   this.WriteObject( converted );
  }

  protected object WmiConvert( object obj )
  {
   if( null == obj )
    return null;

   object newObj = obj;


   Type objType = obj.GetType();

   TypeCode objTypeCode = Type.GetTypeCode( objType );
   String objTypeName = objType.FullName;
   
   if( objType.IsGenericType )
    return obj;

   switch ( objTypeCode )
   {
    case TypeCode.String:
     return obj;
   }

   switch ( objTypeName  )
   {
    case "System.TimeSpan":
     return ( (TimeSpan)obj ).Ticks;

    case "System.Int16":
    case "System.UInt16":
     return System.Convert.ToInt32( obj );

    case "System.UInt64":
    case "System.UInt32":
     return System.Convert.ToInt64( obj );

    case "System.Byte":
     return null;

    case "MongoDB.Driver.Document":
     return obj;
   }

   if( objType.IsArray )
   {
    ArrayList aTmp = new ArrayList();
    foreach ( var s in (object[])obj )
    {
     aTmp.Add( WmiConvert( s ) );
    }
    return aTmp;
   }

   if( 0 == objTypeName.IndexOf( "System.Management." ) )
   {
    Document tmpdoc = null;

    switch( objTypeName )
    {
     case "System.Management.ManagementObject":
     case "System.Management.ManagementBaseObject":
      tmpdoc = new Document();
      ManagementBaseObject mbo = (ManagementBaseObject) obj;
      tmpdoc.Add( "WmiPath", mbo.SystemProperties["__PATH"].Value );
      tmpdoc.Add( "WmiServer", mbo.SystemProperties["__SERVER"].Value );
      AddPropsToDoc( tmpdoc, mbo.Properties );

      newObj = tmpdoc;
      break;

     default:
      break;
    }

    return newObj;
   }
   return newObj;
  }

  protected void AddPropsToDoc( Document doc, object obj )
  {
   foreach ( var propData in (PropertyDataCollection)obj )
      {
       doc.Add( propData.Name, WmiConvert( propData.Value )  );
      }
  }
 }

Hope this helps.

Friday, May 14, 2010

Enumerating Powershell NoteProperties

I recently was asked to stuff a custom PSObject into a bunch of key value pairs, so I thought I'd put it here. Is there a better way?

$props = ($File | get-member -MemberType NoteProperty)
foreach( $p in $props )
{
     # write-verbose (invoke-expression "`$File.$($p.Name)")
     $doc.Add( $p.Name, (invoke-expression "`$File.$($p.Name)") )
}

Tuesday, May 11, 2010

Powershell grep'ing

I've been asked about searching and replacing in files a few times, so I thought I'd put an example up here. This is a way to do it - and you'll almost certainly want to change it around to better suit your scenario.

cd C:\Users\michael.DOMAIN\Workspace\Powershell
function pgrep
{
 Param (
 
  [string]
  [parameter(mandatory=$true)]
  $Like,
 
  [bool]
  $Recurse = $false,
  
  [string]
  $BasePath
 )
 
 Process {
  if( -not $BasePath )
  {
   $BasePath = $PWD
  }
  
  # there's gotta be a slicker way
  $recurse_string = ""
  if( $Recurse )
  {
   $recurse_string = "-Recurse"
  }
  
  Invoke-Expression "Get-ChildItem -Path $BasePath $recurse_string" | 
  where {$_.PSIsContainer -eq $false } |
  foreach {
 
   $file = $_
   # $file.FullName
   # Get-Content -Path $file.FullName | where { $_ -eq "MachineName" }
   if( Get-Content -Path $file.FullName | where { $_ -like $Like } )
   {
    $file
   }
  } 
 }
}

function preplace
{
 Param (
  [string]
  $Path,
  
  [string]
  $From,
  
  [string]
  $To
 )
 
 Process {
  $fi = New-Object -TypeName System.IO.FileInfo -ArgumentList $Path
  $tmpfile = "$($fi.DirectoryName)\$($fi.Name).tmp"
  Remove-Item -Path $tmpfile -ErrorAction SilentlyContinue
 
  Get-Content $Path | 
   foreach {
    $line = $_
    $line.Replace( $From, $To )
   } |
   Add-Content -Path $tmpfile
  
  Remove-Item -Path $Path -ErrorAction SilentlyContinue
  Rename-Item -Path $tmpfile $Path
 }
}


pgrep -Like "*MachineName*" -BasePath C:\Users\michael.DOMAIN\Workspace\Powershell |

foreach {
 $fi = $_
 Write-Host "updating $($fi.FullName)"
 preplace -Path $fi.FullName -From "MachineName" -To "MachineFoo"
}

Sunday, May 2, 2010

Getting Command Line Parameters Using Powershell

I'm just going to leave this here...
(gwmi win32_process -filter "name='powershell.exe'").commandLine

Friday, April 2, 2010

Emacs, Clojure, and Windows 7

Okay, I had to wrestle with this. Maybe that makes me dumb, but if you're reading this, then you ain't doin' much better. I've had an on-and-off again, love/hate relationship with emacs over the years, and I'm swinging back to "on/love" while dinking around with Clojure. Emacs really is the best Lisp-type environment, even on Windows.

To give credit where due, I started with this good post on freegeek.in, but some bits were outdated.

Pre-requisites

First, get emacs installed. Find the latest version in this folder, and extract it someplace - no installation is really necessary.

You also need git. Let's assume you get through all of that.

Last, but not least, you should have a JDK installed.

Add the path to git and java.exe to your PATH, and set JAVA_HOME to your JDK. If you don't want to do that, then start a command prompt, set them manually, and do anything emacs-y from there.
set PATH=%PATH%;c:\sys\git\bin;c:\sys\emacs-23.1\bin
set JAVA_HOME=c:\program files\Java\jdk1.6.0_19
runemacs

Emacs Starter Kit

Next, install the Emacs Starter Kit. This is a huge time-saver. Many of my previous complaints about emacs tended to be having to learn so much just to modify the environment. This takes care of a majority of that. One of the nice, and really important bits is ELPA - a package management system for emacs. In one fell swoop, 80% of my complaints have been silenced.

Anyway, download the ESK from github

git clone git://github.com/eschulte/emacs-starter-kit.git C:\Users\<userdirectory>\AppData\Roaming\.emacs.d

If you have a C:\Users\<userdirectory>\AppData\Roaming\.emacs file, rename it. You can copy it to custom.el, and it will be used as normal. Most of the action occurs in init.el, so that's a good place to look if you really don't like something.

Nope, we're not quite there yet. Before you can use it, you need to install org-mode.

cd C:\Users\<userdirectory>\AppData\Roaming\.emacs.d
git submodule init
git submodule update


Fire up emacs, and M-x package-list-packages. Scroll right on by that tempting "clojure-mode", and put your cursor on "swank-clojure", then press "i" (to select it for installation), then "x" (to start the installation).


Okay, here's where I ran into a problem: when trying to use ELPA, I got the following error: "Local variables entry is missing the suffix". The nice thing about obscure error messages is that they are usually pretty easy to search on. (There's a patch here, only the file name is "package.el"

You'll be adding a function, and modifying package-unpack-singe to use it.

(defun package-write-file-no-coding (file-name excl) 
 (setq buffer-file-coding-system 'no-conversion) 
 (write-region (point-min) (point-max) file-name nil nil nil excl))

The ESK instructions say to build org-mode after that, but launching emacs seemed to take care of that.

Using it

Woooo! Installed! Isn't this easier than NetBeans? (well, actually "yes" for me, since it was some frustration with Enclojure that drove me back to emacs)

Launch emacs, and type M-x slime. If you have everything set up right, you should be prompted to install clojure. This will not only install clojure, but also get you the swank-clojure.jar you'll be needing for projects.

Projects

Assuming you got your SLIME prompt in the step before, creating a project is easy, but not as easy as it could be.

Create the following directory structure wherever it is you want your project to go:

root
  +--src
  +--lib
  +--classes
In the lib directory, put your clojure, clojure-contrib, and swank-clojure jars. You can find them in C:\Users\<username>\AppData\Roaming\.swank-clojure Then you should be able to start a new project with:

M-x swank-clojure-project

That should do it - hope it helps

Tuesday, January 5, 2010

Cleaning up OpenNMS Assets

I've had OpenNMS running on the network for awhile, and here's a problem I ran into: my network is too dynamic. Specifically, it doesn't play nice with DHCP clients. Every time the IP address changes, OpenNMS considers it a new node.

What's screwed up is if you delete the old nodes, the asset info sticks around, even if you didn't add any actual asset information.

I got things straightened up enough that OpenNMS and I are getting along fairly well. There was still all this old asset information gumming up the works. I didn't see anything in the UI or help to get rid of them, so I did it the hard way.

Log into the postgres box hosting the database, and don't forget to use it. Then run the following:

delete from assets 
using node
where node.nodeid = assets.nodeid
and node.nodetype = 'D'

That should clear it up, and it doesn't appear to break anything. If you have any trouble after running this, please let me know in the comments, and I'll look into it (since it will probably be a problem for me, too).

Hope this helps.

Tuesday, August 4, 2009

Svnserve, and Solaris 10

I had to go through the trouble of getting svnserve to run as an SMF-managed service on Solaris 10, so there's no reason you should, too.

Create the method script.


This script uses rc-like syntax. The xml manifest (coming up!) uses this.

vi /lib/svc/method/svc-svnserve

The contents:
#!/sbin/sh

case $1 in
start)
svnserve -r /var/svnroot -d ;;
stop)
/usr/bin/pkill -x -u 0 svnserve ;;
*)
echo Usage is $0 { start | stop }
exit 1 ;;
esac

exit 0

Fix the permissions:

chmod 555 /lib/svc/method/svc-svnserve
chown root:bin /lib/svc/method/svc-svnserve

Test it with:

sh /lib/svc/method/svc-svnserve start

Try to connect, list, etc., make sure it works the way you want it to.

Create the SMF manifest


vi /var/svc/manifest/site/svnserve.xml

The manifest, itself


<?xml version="1.0"?>
<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
<service_bundle type='manifest' name='SUNWsvn:svnserve'>
<service
name='site/svnserve'
type='service'
version='1'>
<single_instance/>
<dependency
name='loopback'
grouping='require_all'
restart_on='error'
type='service'>
<service_fmri value='svc:/network/loopback:default'/>
</dependency>

<exec_method
type='method'
name='start'
exec='/lib/svc/method/svc-svnserve start'
timeout_seconds='30' />
<exec_method
type='method'
name='stop'
exec='/lib/svc/method/svc-svnserve stop'
timeout_seconds='30' />
<property_group name='startd' type='framework'>
<propval name='duration' type='astring' value='contract'/>
</property_group>
<instance name='default' enabled='true' />
<stability value='Unstable' />
<template>
<common_name>
<loctext xml:lang='C'>
New service
</loctext>
</common_name>
</template>
</service>
</service_bundle>

Check your work


Check the xml with:

xmllint --valid /var/svc/manifest/site/svnserve.xml

Then let's see if the smf stuff likes it:

svccfg validate /var/svc/manifest/site/svnserve.xml

If everything looks good so far...

Importing the manifest


svccfg import /var/svc/manifest/site/svnserve.xml

It should show up under svcs in maintenance. Let's fix that:

svcadm enable svnserve:default

If it doesn't start, check /var/svc/log/site-svnserve:default.log

You should be all nicely integrated now.

Saturday, July 18, 2009

Some FileInfo Extensions

I kept on needing the same stuff regarding files when writing C#, so I came up with a set of helpers implemented as extensions to the FileInfo class.

Nothing particularly earth-shattering, but you might find them useful.

  • IsDirectory - does the obvious
  • GetMimeType - uses Windows' urlmon.dll to magically determine a file's mime type.
  • GetFileBytes - gets a chunk off the front of a file.
  • GetSha1, and friends - Computes the SHA1 hash of a file. Configurable buffer size.
  • ApplyToFolder - accepts a function to be applied to every file in a hierarchy.

Latest version here.

using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;

namespace QSha
{
public static class FileInfoExtensions
{
public static bool IsDirectory( this FileInfo fi )
{
if ( !( ( FileAttributes.Directory & fi.Attributes ) == FileAttributes.Directory ) )
{
return false;
}
return true;
}


public static byte[] GetFileBytes( this FileInfo fi, long maxBufSize )
{
byte[] buffer = new byte[( fi.Length > maxBufSize ? maxBufSize : fi.Length )];
using ( FileStream fs =
new FileStream( fi.FullName, FileMode.Open, FileAccess.Read, FileShare.Read, buffer.Length ) )
{
fs.Read( buffer, 0, buffer.Length );
fs.Close();
}

return buffer;
}

public static void ApplyToFolder( this FileInfo fi, Func fFileFound )
{
string[] subFolders;
try
{
subFolders = Directory.GetDirectories( fi.FullName );
}
catch ( UnauthorizedAccessException )
{
return;
}

string[] files;
foreach ( string folder in subFolders )
{
FileInfo tmpFi = new FileInfo( folder );
tmpFi.ApplyToFolder( fFileFound );

try
{
files = Directory.GetFiles( folder );
}
catch ( UnauthorizedAccessException )
{
continue;
}

foreach ( string file in files )
{
bool ffres = fFileFound( new FileInfo( file ) );

// we don't do any post-processing, so these are wasted cycles
/*
if ( !ffres )
continue;
*/
}
}
}

// mime-type stuff
public static string GetMimeType( this FileInfo fi )
{

if ( fi.IsDirectory() )
throw new FileNotFoundException( String.Format( "Is a directory, not a file: {0}", fi.FullName ) );

if ( !File.Exists( fi.FullName ) )
throw new FileNotFoundException( fi.FullName + " not found" );


byte[] buffer = new byte[256];
using ( FileStream fs = new FileStream( fi.FullName, FileMode.Open ) )
{
if ( fs.Length >= 256 )
fs.Read( buffer, 0, 256 );
else
fs.Read( buffer, 0, (int)fs.Length );
}
try
{
System.UInt32 mimetype;
FindMimeFromData( 0, null, buffer, 256, null, 0, out mimetype, 0 );
System.IntPtr mimeTypePtr = new IntPtr( mimetype );
string mime = Marshal.PtrToStringUni( mimeTypePtr );
Marshal.FreeCoTaskMem( mimeTypePtr );
return mime;
}
catch ( Exception )
{
return "unknown/unknown";
}
}

[DllImport( @"urlmon.dll", CharSet = CharSet.Auto )]
private extern static System.UInt32 FindMimeFromData(
System.UInt32 pBC,
[MarshalAs( UnmanagedType.LPStr )] System.String pwzUrl,
[MarshalAs( UnmanagedType.LPArray )] byte[] pBuffer,
System.UInt32 cbSize,
[MarshalAs( UnmanagedType.LPStr )] System.String pwzMimeProposed,
System.UInt32 dwMimeFlags,
out System.UInt32 ppwzMimeOut,
System.UInt32 dwReserverd
);
// /mime-type stuff

// hash stuff
public static string GetSha1Base64( this FileInfo fi, long maxBufSize )
{
return Convert.ToBase64String( fi.GetSha1( maxBufSize ) );
}

public static string GetSha1Hex( this FileInfo fi, long maxBufSize )
{
byte[] hash = fi.GetSha1(maxBufSize);
StringBuilder hex = new StringBuilder( hash.Length );
for ( int i = 0; i < hash.Length; i++ )
{
hex.Append( hash[i].ToString( "X2" ) );
}
return hex.ToString();
}

public static byte[] GetSha1( this FileInfo fi, long maxBufSize )
{
string ret = String.Empty;

if ( 0 == fi.Length )
return null;

if( 0 == maxBufSize )
{
maxBufSize = fi.Length;
}
byte[] buffer = fi.GetFileBytes( maxBufSize );

SHA1Managed sha1 = new SHA1Managed();
return sha1.ComputeHash( buffer );
}
}
}

Sunday, July 12, 2009

Powershell $profile - Is This Great Filler, or What?

Some new java stuff, a couple of nice little helper functions: qfind, for searching the filesystem and title, to change the console title.
$projects = $env:USERPROFILE + "\Documents\Visual Studio 2008\Projects"
$sysdir = $env:USERPROFILE + "\sys"

# misc stuff
new-alias -name npp -value "C:\Program Files\Notepad++\notepad++.exe"
function qfind( $start, $like ) { get-childitem $start -name $like -recurse }

function title( $msg ) { $host.ui.RawUI.WindowTitle = $msg }

# git stuff

$gitexe = $sysdir + "\Git\bin\git.exe"
new-alias -name vi -value $sysdir\Vim\vim72\gvim.exe
$env:EDITOR = "npp"
new-alias -Name git -Value $gitexe

# java stuff

$jdk = "jdk1.6.0_12"
$java_home = "C:\Program Files\Java\$jdk"
$env:JAVA_HOME = $java_home

new-alias -name jruby -value $sysdir\jruby\bin\jruby.bat

new-alias -name jar -value "$java_home\bin\jar.exe"
new-alias -name ant -value "c:\sys\ant\bin\ant.bat"
new-alias -name javac -value "$java_home\bin\javac.exe"
function jetty() { java -jar start.jar etc/jetty.xml }
$env:CATALINA_HOME = "c:\sys\tomcat6"
new-alias -name tomcat -value "c:\sys\tomcat6\bin\startup.bat"

# MS Stuff

new-alias -name nant -value "$sysdir\nant\bin\nant.exe"
new-alias -name msbuild -value C:\Windows\Microsoft.NET\Framework\v2.0.50727\msbuild.exe

title( "General" )

Hope this helps. At least it is harder to lose :)

Update: Once I got to looking at it here, I decided it could be better laid out. So, it is a little prettier, now.

Friday, June 26, 2009

OpenNMS and Windows Monitoring

Now that OpenNMS has discovered my network, how can I get even more out of it?

My first thought was to extend OpenNMS to accommodate what I'm looking for. That's a lot like work, so I've installed and enabled SNMP on one of my Windows 2003 servers.

A little searching turned up this set of instructions for configuring SNMP (because MS' instructions are atrocious. A "configuring snmp" section should do more than tell you what configuring it would get you, if they were planning on being so gracious as to tell you how to do it).

It's under the properties for the service. That's a great place for it - no sarcasm intended. Of course, there's only a couple of other services that do that, so I don't look there.

Anyway...

I configured the community name, and set the destination to the FQDN of the OpenNMS server. Restarted the service, and ta-da! OpenNMS started receiving messages. And complaining about them.

Checked the Security tab, and added the OpenNMS server to the list of "Accept SNMP packets from these hosts" list.

There's a section in the OpenNMS admin section for configuring what IP addresses will be sending traps, and what community name they send. I left it at v1.

It started working after that.

I'm not entirely thrilled with this as a solution. It is known to be pretty insecure. Let's see what kind of data comes through...and I'm just not getting the point. There doesn't seem to be anything new. Maybe SNMP is just too smart for me. Ah well.

Update: I did a little configuration with evntwin.exe, and started forwarding various W3SVC events to OpenNMS. That was all around kludgey, and not really worth the effort.

I still like OpenNMS as a lightweight inventory and monitoring system, though.

Backing up VMWare ESX 3.5

I'd been whining about the troubles I had getting the various parts of a VMWare backup script working. Well, I've got something that appears to fill the bill.

The end result is that I have a backup local to the host, so I can restore very quickly, and as many past snapshots as my Windows server can hold.

The first thing you need to do is open up the firewall:
esxcfg-firewall --enableService smbClient

Note that in order for everything to work, I have to use the FQDN to the server. Otherwise, I'd get an error regarding broadcasts.

Here's the main script:
#!/bin/sh

VMCONFIGLIST=`/usr/bin/vmware-cmd -l`
TODAY=`date +%Y%m%d`
BACKUPBASE=/vmfs/volumes/`hostname`\:raid0/backups

USER=root
PASSWORD=nunyabidnz

WINUSER=NA/meh
WINPW=blah
WINDEST='//server01.example.com/backups'

if [ ! -d ${BACKUPBASE} ]
then
echo "Backup directory ${BACKUPBASE} does not exist."
echo "Exiting"
# no, I don't want to create it. If there's a problem with the path,
# there's no telling where these backups will end up.
exit
fi

echo "Back up for ${TODAY}"
echo "Backup directory ${BACKUPBASE}"

for VM in ${VMCONFIGLIST}
do
# set up the variables for this loop
VMDIR=`dirname ${VM}`
echo "Looking for ${VMNAME} in ${VMDIR}"

# if the config file doesn't exist, we can't do anything
if [ ! -f ${VM} ]
then
echo " * Did not find ${VM}."
echo " * Skipping"
continue
fi

# get the VM name from the config file
VMNAME=`cat ${VM} | awk '/displayName =/ {print $3}' | sed 's/\"//g'`

DESTDIR=${BACKUPBASE}/${VMNAME}

TARNAME=${VMNAME}.${TODAY}.tgz

# the work begins here
# all the configurable stuff should be above this line

echo " - Backing up ${VMNAME}"
echo " - file ${VM}"

# vcbMounter bombs out if the directory already exists
if [ -d ${DESTDIR} ]
then
echo " - deleting directory ${DESTDIR}"
rm -Rf ${DESTDIR}
fi

# create the backup
echo " - Starting vcb..."
/usr/sbin/vcbMounter -h `hostname` -t fullvm -u ${USER} -p ${PASSWORD} -r ${DESTDIR} -a Name:${VMNAME}

# check vcbMounter's return
if [ "$?" -ne "0" ]
then
echo " - Error backing up VM ${VMNAME}"
continue
else
echo " - Successful backup of ${VMNAME}"
fi

# compress it

echo " - Archiving backup to tarfile ${BACKUPBASE}/${TARNAME}"
echo " - to tarfile $TARNAME"
# --force-local to ignore the ":" in the path
tar -C ${BACKUPBASE} --force-local -czf ${BACKUPBASE}/${TARNAME} ${DESTDIR}
echo " - Compression completed"

echo " - Copying to ${WINDEST}"
/usr/bin/smbclient -c "prompt off; put ${BACKUPBASE}/${TARNAME} ${TARNAME}" -U ${WINUSER} ${WINDEST} ${WINPW}

echo "Cleaning up .tgz"
rm -f ${BACKUPBASE}/${TARNAME}

echo " --- ${VMNAME} complete --- "
done

Any suggestions for improvements (how about an occasional function , Mr. Goon? Or check the return from smbclient? Hmmm?) are welcome.

Tuesday, June 23, 2009

MSProject Server Doesn't Exist?

Well, I installed MSProject Server onto a node of the web farm, and ran into a snag. When I tried to administer it via shared services, I got this error:
The Project Application Service doesn't exist or is stopped. Start the Project Application Service.

Checked the service, it was running according to the MOSS UI. Services MMC showed the other services as running. Nothing interesting in the event log.

Searched around, and found others with this problem. The most common suggested fix was
stsadm -o provisionservice -action start -servicetype "Microsoft.Office.Project.Server.Administration.ProjectApplicationService, Microsoft.Office.Project.Server.Administration, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71E9BCE111E9429C" -servicename ProjectApplicationService

Well, that didn't do it.

The solution? I could about kick myself. MSProject server needs to be installed on all nodes of the farm. It even says it in the instructions. Dumbass me...

Monday, June 22, 2009

vmware-cmd Not Working

I'm still working on those VM backups. I got everything started okay on the first node. It wasn't until the second node that I ran into other problems. Of course.

Attempting to run vmware-cmd resulted in the following:

Can't locate VMware/VmPerl.pm in @INC (@INC contains: blib/arch -Iblib/lib -I/usr/lib/perl5/5.6.0/i386-linux -I/usr/lib/perl5/5.6.0 -I. /usr/lib/perl5/5.8.0/i386-linux-thread-multi /usr/lib/perl5/5.8.0 /usr/lib/perl5/site_perl/5.8.0/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.0 /usr/lib/perl5/site_perl/5.8.0 /usr/lib/perl5/site_perl /usr/lib/perl5/vendor_perl/5.8.0/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.0 /usr/lib/perl5/vendor_perl/5.8.0 /usr/lib/perl5/vendor_perl /usr/lib/perl5/5.8.0/i386-linux-thread-multi /usr/lib/perl5/5.8.0 . blib/arch blib/lib /usr/lib/perl5/5.6.0/i386-linux /usr/lib/perl5/5.6.0 .) at /usr/bin/vmware-cmd line 133.
/usr/bin/vmware-cmd requires the VMware::VmPerl Perl libraries to be installed.
Check that your installation did not encounter errors.

According to some stuff I found, this can be caused by clock-skew when the server is installed. Of course, I don't care about why it happened (just good to know). How to fix it?
# vmware-config.pl

Please specify a port for remote console connections to use [902]

Stopping xinetd: [ OK ]
Starting xinetd: [ OK ]
Configuring the VMware VmPerl Scripting API.

Building the VMware VmPerl Scripting API.

Using compiler "/usr/bin/gcc". Use environment variable CC to override.

Installing the VMware VmPerl Scripting API.

The installation of the VMware VmPerl Scripting API succeeded.

The configuration of VMware ESX Server 3.5.0 build-123630 for this running
kernel completed successfully.
And that cleared it up.

smbclient Woes on ESX

I'm writing a backup script for our ESX hosts, and I ran into a problem connecting to the Windows server.

After opening the firewall with
esxcfg-firewall -e smbclient

I still got an error attempting to connect to the Windows machine:

[root@ESX backups]# smbclient -U DOM\\adminusers //server01/backups password
Packet send failed to 10.4.136.255(137) ERRNO=Operation not permitted
Connection to server01 failed

Okay, so the firewall is blocking broadcasts (that ".255" at the end). The solution was to negate the need for the broadcast. smbclient was unable to resolve the IP address given just the hostname of "server01", and was attempting a netbios broadcast (I think).

The solution was to use the FQDN to server:

[root@ESX backups]# smbclient -U DOM\\adminuser //server01.example.com/backups password
Domain=[DOM] OS=[Windows Server (R) 2008 Enterprise 6001 Service Pack 1] Server=[Windows Server (R) 2008 Enterprise 6.0]
smb: \>

Friday, June 19, 2009

OpenNMS as a Windows Service

[I've updated this some, to correct errors and be more thorough]

I'm doing some testing with OpenNMS, to see if it is at least good enough. So far, it is.

One of the complications is that it is a java app. This would be fine, except it doesn't ship with a means of running it as a Windows service. All in all, it wasn't too bad. I got it running on Windows 2003 Server - I haven't tried 2008, yet.

All of this assumes that you have OpenNMS itself working.

I started with the instructions here, using "Method One".

The abbreviated version of those instructions is that inside the downloaded .zip file, there's a file structure which looks like the one in your OpenNMS directory.

Unzip that to someplace other than your OpenNMS directory - I know how you people are - so we can make some changes.

Delete the ./src directory. If you're reading this, you aren't using that.

In the ./bin directory, there's a bunch of batch files. I renamed them "WrapperInstall.bat", "WrapperStart.bat", etc., because that's just easier to keep track of.

In ./conf, there's a file named wrapper.conf. Try using this one, but double-check the directory names....

#********************************************************************
# Wrapper License Properties (Ignored by Community Edition)
#********************************************************************
# Include file problems can be debugged by removing the first '#'
# from the following line:
##include.debug
#include ../conf/wrapper-license.conf
#include ../conf/wrapper-license-%WRAPPER_HOST_NAME%.conf

#********************************************************************
# Wrapper Java Properties
#********************************************************************
wrapper.java.command=C:\Program Files\Java\jdk1.6.0_14\bin\java
wrapper.java.additional.1=-Xmx256m
wrapper.java.additional.2=-Dopennms.home="C:/PROGRA~1/OpenNMS"

wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp
wrapper.app.parameter.1= org.opennms.bootstrap.Bootstrap
wrapper.app.parameter.2= start

wrapper.java.classpath.1=C:/Program Files/Java/jdk1.6.0_14/lib/tools.jar
wrapper.java.classpath.2=../lib/wrapper.jar
wrapper.java.classpath.3=../lib/opennms_bootstrap.jar

wrapper.java.library.path.1=../lib

wrapper.java.additional.auto_bits=TRUE

#********************************************************************
# Wrapper Logging Properties
#********************************************************************

wrapper.console.format=PM
wrapper.console.loglevel=WARN
wrapper.logfile=../logs/wrapper.log
wrapper.logfile.format=LPTM
wrapper.logfile.loglevel=INFO

wrapper.logfile.maxsize=0
wrapper.logfile.maxfiles=0

wrapper.syslog.loglevel=NONE

#********************************************************************
# Wrapper Windows Properties
#********************************************************************

wrapper.console.title=OpenNMS

#********************************************************************
# Wrapper Windows NT/2000/XP Service Properties
#********************************************************************

wrapper.ntservice.name=opennms

wrapper.ntservice.displayname=OpenNMS
wrapper.ntservice.description=Network Management System

wrapper.ntservice.starttype=AUTO_START
wrapper.ntservice.interactive=false

Copy all of the wrapper files into their corresponding OpenNMS directories. If the destination directory doesn't exist (./conf), create it.

Almost there...

Go into the ./bin directory of your OpenNMS installation, and double-click the WrapperInstall.bat file.

Now, you should be able to click on WrapperStart.bat (you did rename it, right?), or go into the Services MMC and start it from there.

Finding Event Log Messages With Powershell

Wooo! Big update!

Actually, I just don't want to lose this...
get-eventlog -ComputerName dalmobdev08 -logname application | where-object {$_.Message -match "corrupt"} | select-object -First 10


Finds event log entries with the word "corrupt" in the message.

Wednesday, June 10, 2009

Listing Add/Remove Programs with Powershell, redux

Man, I barely get the thing posted, and already there's complaints about having to install stuff.

Okay, fine:

$target = "somecomputer"

$arp_key = "Software\Microsoft\Windows\CurrentVersion\Uninstall"
$type = [Microsoft.Win32.RegistryHive]::LocalMachine
$hive = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($type, $target)

$regkey = $hive.OpenSubKey($arp_key)

foreach( $subkey_name in $regkey.GetSubKeyNames() )
{
$subkey = $hive.OpenSubKey( $arp_key + "\" + $subkey_name )
$display_name = $subkey.GetValue( "DisplayName" )
$display_version = $subkey.GetValue( "DisplayVersion" )

if( $display_name -ne [string].Empty )
{
write-host @($display_name + " (" + $display_version + ")")
}

# foreach( $val_name in $subkey.GetValueNames() )
# {
# write-host "name: " $val_name -nonewline */
# write-host "value: " $subkey.GetValue( $val_name )
# }
}


No installation required. It is rather naive - if there is no display name, then it is skipped. If you've got a better version, please let me know. This one feels icky, to me.

I left in a chunk, remarked out, to show how to get to the other values.

Listing Add/Remove Programs with Powershell

Shamelessly stole this from here, which apparently stole it from someplace else...

First, run this:
set-content RegProgs.mof @'
#pragma namespace("\\\\.\\root\\cimv2")
instance of __Win32Provider as $Instprov
{
Name ="RegProv" ;
ClsID = "{fe9af5c0-d3b6-11ce-a5b6-00aa00680c3f}" ;
};
instance of __InstanceProviderRegistration
{
Provider =$InstProv;
SupportsPut =TRUE;
SupportsGet =TRUE;
SupportsDelete =FALSE;
SupportsEnumeration = TRUE;
};

[dynamic, provider("RegProv"),
ProviderClsid("{fe9af5c0-d3b6-11ce-a5b6-00aa00680c3f}"),ClassContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall")]
class win32reg_arp
{
[key]
string ProdID;
[PropertyContext("DisplayName")]
string DisplayName;
[PropertyContext("Publisher")]
string Publisher;
[PropertyContext("DisplayVersion")]
string Version;
};

'@

It will create a file named "RegProgs.mof". This file is used by mofcomp.exe, which "compiler parses a file containing MOF statements and adds the classes and class instances defined in the file to the WMI repository. The following code example shows how to run the MOF compiler on a file." (Source)

Run:
mofcomp.exe RegProgs.mof

This will compile and add it to the local WMI repository.

Then, from PowerShell, you can
Get-WmiObject win32reg_arp

The .mof needs to be installed on any machine which you wish to scan.

Update: I have a non-.mof version here.

Tuesday, May 26, 2009

My vimrc, Let Me Show You It

Short but sweet...

syntax on
set wildmode=list:longest,full
set autoindent
nnoremap :bnext
nnoremap :bprevious
set number
set guifont=Anonymous:h9:cANSI
set ts=4



The "set guifont" is for gVim. Anonymous is a nice, free programming font.