• New MD5 based backup script

    I found this use of md5 and find the other day. I based my current backup script around it. The md5 will show if anyone modifies a file, or adds/removes a file in the web hosting root (/var/www) or in the config directory (/etc/httpd/conf.d/). If there is a change then zip each site up individually and move to a backup folder to be rsynced to other servers.

    NewWWWMD5=$(find /var/www/ -type f -exec md5sum {} \; | md5sum - | awk '{print $1}')
    OldWWWMD5=$(cat $PARENTDIR/_var_www_*.md5)
    NewConfMD5=$(find /etc/httpd/conf.d/ -type f -exec md5sum {} \; | md5sum - | awk '{print $1}')
    OldConfMD5=$(cat $PARENTDIR/_etc_httpd_conf.d_*.md5)
    
    if [ $NewWWWMD5 = $OldWWWMD5 -a $NewConfMD5 = $OldConfMD5 ]; then
    	echo "Neither /var/www/ nor /etc/httpd/conf.d/ have changed"
    else
    	rm -rf $BACKUPDIR/*Files
    	echo "/var/www or /etc/httpd/conf.d has changed"
    	mkdir -p $BACKUPDIR-Files
    
    	# backup /var/www
    	for directory in /var/www/*; do
    	  	if [ -d $directory ]; then
    	    	bu $directory;
    	    fi
    	done
    
    	# replace previous /var/www MD5
    	rm -f $PARENTDIR/_var_www_*.md5
    	find /var/www/ -type f -exec md5sum {} \; | md5sum - | awk '{print $1}' > $PARENTDIR/_var_www_$CURRENTDAY.md5
    
    	#backup /etc/httpd/conf.d
    	bu "/etc/httpd/conf.d"
    
    	# replace previous /etc/httpd/conf.d MD5
    	rm -f $PARENTDIR/_etc_httpd_conf.d_*.md5
    	find /etc/httpd/conf.d/ -type f -exec md5sum {} \; | md5sum - | awk '{print $1}' > $PARENTDIR/_etc_httpd_conf.d_$CURRENTDAY.md5
    fi

    Seems to work!


  • PowerShell is great

    Okay, I drank the Kool-Aid. PowerShell is awesome. The first thing I wanted to do was make sure my $profile is always the most current no matter what machine was on. In the past I had a batch file that I would run that would open my command prompt the way I wanted. I modified that so if PowerShell is installed, then get my profile up-to-date and then launch PowerShell. This is part of my current batch file:

    IF NOT EXIST "c:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" GOTO NO_PS
    powershell -NoProfile $a=(Split-Path $profile -parent);if (!(Test-Path $a)) {New-Item $a -type directory};
    powershell -NoProfile if (!(Test-Path $profile)) {Copy-Item %~dp0Scripts\Microsoft.PowerShell_profile.ps1 (Split-Path $profile -parent)}
    powershell -NoProfile if (!(Compare-Object $(Get-Content $profile) $(Get-Content Scripts\Microsoft.PowerShell_profile.ps1)).Count -eq 0 ) {Copy-Item Scripts\Microsoft.PowerShell_profile.ps1 (Split-Path $profile -parent)}
    @start  %COMSPEC% /K PowerShell -nologo

    This will copy over my profile if it does not exist or is a different version. Now when I am on a server with PowerShell I can double click my batch file and my environment is up to date!


  • Using a sub-select to find machines that do not have the most recent version of a package.

    Many people have blogged about this – how to find machines that don’t have the most recent version of a package installed.

    First we write a query to show machines that don’t have the software installed (in this case firefox)
     select SMS_R_System.Name,SMS_R_System.LastLogonUserName
    	from SMS_R_System
    		inner join SMS_G_System_SYSTEM on SMS_G_System_SYSTEM.ResourceID = SMS_R_System.ResourceId
    	where SMS_R_System.Client = 1
    		and SMS_G_System_SYSTEM.SystemRole = "Workstation"
    		and SMS_G_System_SYSTEM.Name not in (
    			select SMS_R_System.Name
    			from  SMS_R_System inner join SMS_G_System_ADD_REMOVE_PROGRAMS on SMS_G_System_ADD_REMOVE_PROGRAMS.ResourceID = SMS_R_System.ResourceId
    			where SMS_R_System.Client = 1
    			and SMS_G_System_ADD_REMOVE_PROGRAMS.DisplayName like "Mozilla Firefox%")
    
    Next we write a query to show the machines that have the most recent software installed (this is used in the following query):
    select SMS_R_System.Name, SMS_R_System.LastLogonUserName, SMS_G_System_ADD_REMOVE_PROGRAMS.DisplayName,
    			SMS_G_System_ADD_REMOVE_PROGRAMS.Version
    	from  SMS_R_System
    		inner join SMS_G_System_ADD_REMOVE_PROGRAMS on SMS_G_System_ADD_REMOVE_PROGRAMS.ResourceID = SMS_R_System.ResourceId
    	where SMS_R_System.Client = 1
    		and SMS_G_System_ADD_REMOVE_PROGRAMS.DisplayName like "Mozilla Firefox%"
    		and SMS_G_System_ADD_REMOVE_PROGRAMS.Version = "3.6.3 (en-US)"
    	order by SMS_R_System.Name

    Finally we write a query to show machines that aren’t in the query above

    	select SMS_R_System.Name, SMS_R_System.LastLogonUserName, SMS_G_System_ADD_REMOVE_PROGRAMS.DisplayName, SMS_G_System_ADD_REMOVE_PROGRAMS.Version
    	from  SMS_R_System inner join SMS_G_System_ADD_REMOVE_PROGRAMS on SMS_G_System_ADD_REMOVE_PROGRAMS.ResourceID = SMS_R_System.ResourceId
    	where SMS_R_System.Client = 1
    		and SMS_G_System_ADD_REMOVE_PROGRAMS.DisplayName like "Mozilla Firefox%"
    		and SMS_R_System.Name not in (
    			select SMS_R_System.Name
    			from  SMS_R_System inner join SMS_G_System_ADD_REMOVE_PROGRAMS on SMS_G_System_ADD_REMOVE_PROGRAMS.ResourceID = SMS_R_System.ResourceId
    			where SMS_R_System.Client = 1
    			and SMS_G_System_ADD_REMOVE_PROGRAMS.DisplayName like "Mozilla Firefox%"
    			and SMS_G_System_ADD_REMOVE_PROGRAMS.Version = "3.6.3 (en-US)")
    order by SMS_R_System.Name

    Import the First and Third queries into a collection and we have a collection that shows machines that need the updated package (including machines that don’t have any version of the package installed.)


  • How I created a “Copy to new item” functionality for a SharePoint list – Part 2

    Second part. First Part can be found here. On the second page (NewForm.aspx), I grabbed out of the querystring the values for the source list item and the name of the list.
    I used this person’s query string parser.

    Then I used the following SOAP query :

    $(document).ready(function() {
     var sourceID = getQuerystring('SourceID');
     var listName = getQuerystring('ListName');
    
     var soapEnv = "<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/'> \
    <soapenv:Body> \
    <GetListItems xmlns='http://schemas.microsoft.com/sharepoint/soap/'> \
    <listName>" + listName + "</listName> \
    <viewName>{GUID}</viewName> \
    <viewFields /> \
    <ViewFields /> \
    <query> \
    <Query><Where> \
    <Eq> \
    <FieldRef Name='ID' /> \
    <Value Type='Integer'>" + sourceID + "</Value> \
    </Eq> \
    </Where></Query>\
    </query> \
    </GetListItems> \
    </soapenv:Body> \
    </soapenv:Envelope>";
    
     $.ajax({
     async: false,
     url: "http://site.com/subsite/_vti_bin/lists.asmx",
     type: "POST",
     dataType: "xml",
     data: soapEnv,
     complete: processResult,
     contentType: "text/xml; charset=\"utf-8\""
     });
    
     });
     function processResult(xData, status) {
     $(xData.responseXML).find("z\\:row").each(function() {
     $("input[title='Input']").val($(this).attr("ows_Input"));
     $("textarea[title='TextArea']").val($(this).attr("ows_TextArea"));
     $("select[title='DropDown']").val($(this).attr("ows_DropDown")).attr("selected", "selected"); 
     }
     )};
    

    In the last three lines I changed the input box, textbox and dropdown boxes to their values in the results fromt the SOAP query.

    Kinda fun. Just need to figure out how to do check boxes!


  • How I created a “Copy to new item” functionality for a SharePoint list – Part 1

    I wanted to create a “copy to new item” functionality for a SharePoint list.

    Steps I came up with:

    1. The first thing I had to do was add a link to the context menu (I learned that it is called an ECB) and have it point to the NewForm.aspx.
    2. Once I got that, I could append a querystring variable to the url that contained the “Source ID” of the item to copy and the name of the current list.
    3. Then I would grab that querystring value on the other side – in the NewForm.aspx page
    4. Next I would use that variable to query the SharePoint List via SOAP
    5. Inject the results the  into the form

    Here is my script (add to a CEWP, I already have the jquery pointers to google in a Delegate control)

    <script language="javascript">
    function Custom_AddListMenuItems(m, ctx) {
    var editURL = window.location.protocol + "//" + window.location.host + ctx.listUrlDir + "/NewForm.aspx?SourceID=" + currentItemID + "&amp;ListName=" + ctx.ListTitle;
     CAMOpt(m, "Copy To New Item" ,"window.location=('" + editURL + "');" , "/_layouts/images/Copy.GIF");
     CAMSep(m);
    }
    </script>
    

    More to come.


  • How to get into Web Part Page Maintenance mode

    For when you screw up a CEWP with bad code, you can use the query string “contents=1” to remove the offending webpart.


  • How to add a webpart to a Sharepoint “NewForm.aspx”

    I wanted to put a hidden CEWP on top of a standard SharePoint input form (you know when you click “NEW” too add an item to a list). The edit page was grayed out. I added to the querystring “NewForm.aspx?ToolPaneView=2” and I can add the CEWP to the top of the page. Once I added that, the edit page option is no longer grayed out.


  • BASH (readline) keyboard shortcuts

    I was just in training and the instructor was a command line keyboard shortcut wizard. He was magically making words disappear and reappear. So i fond this list of shortcuts. Many of them did not work in my OS X BASH prompt.I fond I had to go into the terminal.app preferences and select “use option key as meta key” on the keyboard tab (it is at the bottom). Now I can add a few shortcuts to my repertoire.