PowerShell to create Aliases for all your functions

I have a naming convention for all the function that I write, for example: JBMURPHY-AD-GetGroup. I wanted to create aliases for all my functions with my employers’s name, for example CompanyName-AD-GetGroup. I created the following function to “grep” all the function names and create an “Alias” file. This file would have all the set-alias commands that would be sourced on PowerShell start up. This function contains Regular Expressions (my weakness), which I borrowed from here.

FUNCTION JBMURPHY-CreateAliases{
PARAM($OLDNAME="JBMURPHY-",$NEWNAME="CompanyName-")
$tempFile = [System.IO.Path]::GetTempFileName()

Select-String -Pattern "function\s+(\w+-\w+-\w+)\b" *.ps1 | %{
$FUNCTIONS=$_.Matches | %{$_.groups[0].Value -Replace "Function ",""}
Write-host "set-alias $($FUNCTIONS -Replace $OLDNAME,$NEWNAME) $FUNCTIONS -Option AllScope"
Out-File $tempFile -encoding ascii -append -inputobject "set-alias $($FUNCTIONS -Replace $OLDNAME,$NEWNAME) $FUNCTIONS -Option AllScope"
}
move-item $tempFile "$($NEWNAME)ALIASES.ps1" -force
}

PowerShell, Active Setup and running a SCCM package “before log on”

I have been struggling with the following idea for a while: How to run a package before before a person logs on using SCCM. There is a setting in SCCM that runs when no one is logged on, but if a person reboots and logs on before SCCM fires, the package will never run. Basically I wanted the ability to make SCCM work like Software Deployment in AD (AD prevents you from logging on until software is completely installed).

The missing piece, for me, was “Active Setup”. Active Setup is pretty well documented here. Combining Active Setup with PowerShell and SCCM, I believe I can run packages before people log on (or at least before they launch any programs).

Here are my steps

  • Step 1 : I need to create an Active Setup registry entry on everyone’s machine that will run a PowerShell script
    • I created this PowerShell script to create the Active Setup registry entries. This will put a StubPath that launches the PowerShell script.
  • Step 2 : Pop up an info message telling the user we are doing some work before the finish logging in.
  • Step 3 : Launch the SCCM Advertised program that you want. Since Active Setup is running as the user, you have to use SCCM to run anything that needs “administrative privileges”. The following code is used inside a PowerShell script to launch an advertisement on the local machine (you need to know the ProgramID and the PackageID):
Function JBMURPHY-SCCM-UIExecuteProgram {
 Param([parameter(Mandatory = $true)]$ProgramID,
       [parameter(Mandatory = $true)]$PackageID)
 $UIResource = New-Object -ComObject UIResource.UIResourceMgr
 $UIResource.ExecuteProgram($ProgramID, $PackageID,$true)
}

Kinda complicated, but I think it will work. Have you used these methods?

Dotted (period) NetBIOS Domain Name issues

I inherited a Dotted Netbios Domain Name. Technically it is allowed, but it is not recommended. With every new version of software, I cringe in fear that it will come back to bite us again. For example:

  1. Moving from Exchange 2003 to 2010 was a problem for a while, but it seemed to been resolved and we migrated from 2003 to 2010 with out issue.
  2. When I tried to upgrade SCCM 2007 to SP 2, it failed as I describe in this thread. I had to install fresh from a slipstreamed  installer.
  3. Most recently, when I try to install CRM 2011 in our dotted domain, it failed. In my reading yesterday, I realized Rollup 4 has the following: “When the NetBIOS name of the domain contains a period (.), the installation of Microsoft Dynamics CRM 2011 fails.”
    • I still can’t add a new organization, but I was able to restore an organization from a dev server in a non-dotted netbios domain.
  4. I will add more as I find them.
The problem seems to be that with each new installer, the developers assume that if there is a period in the domain name, then the user has supplied a FQDN by accident.

PowerShell Query to find a users computer name in SCCM

We rely on Remote Assistance. Usually, I just type “msra /offerra” in to my PowerShell session and lookup a the user’s computer name in the SCCM report named “Computers for a specific user name”. I wanted to make that process quicker. I wrote the following script to query SCCM for the “list of computer’s who’s last logged on user” is the person I am looking for.

FUNCTION JBMURPHY-SCCM-GetComputerByLastLoggedOnUser {
Param([parameter(Mandatory = $true)]$SamAccountName,
	$SiteName="JBM",
	$SCCMServer="SCCMServer.domain.local")
	$SCCMNameSpace="root\sms\site_$SiteName"
	Get-WmiObject -namespace $SCCMNameSpace -computer $SCCMServer -query "select Name from sms_r_system where LastLogonUserName='$SamAccountName'" | select Name
}

Let me know if this is useful to you!

PowerShell scripts to create a WinPE 4.0 wim/ISO

I have been  a WinPE hacker since it was only available to SA subscribers. With Vista it was free to the world, and I started moving all my setup processes to it. I have always used the dos batch scripts found in this forum to create a new WinPE ISO. Since WinPE 4.0 is coming out with Windows 8 (if not before (I don’t know timelines)), I wanted to modify the dos batch files I rely on to work with WinPE 4.0. Since WinPE 4.0 has PowerShell in it, I wanted to migrate those dos batch files to PowerShell functions. Working from the dos batch files linked above and this post I created the functions below. They have numbers in their names because they are the steps to follow when creating a new ISO.


Function JBMURPHY-WinPE-1MakePEDirectory{
	Param($OSArchitecture="x86")

 remove-item -force "c:\PE\winpe_$OSArchitecture"
 New-Item c:\PE\winpe_$OSArchitecture\ISO\sources -type directory -force
 New-Item c:\PE\winpe_$OSArchitecture\mount -type directory -force
 copy-item "C:\Program Files\Windows Kits\8.0\Assessment and Deployment Kit\Windows Preinstallation Environment\$OSArchitecture\winpe.wim" "c:\PE\winpe_$OSArchitecture\ISO\sources\boot.wim"
 copy-item "C:\Program Files\Windows Kits\8.0\Assessment and Deployment Kit\Windows Preinstallation Environment\$OSArchitecture\Media\*" "c:\PE\winpe_$OSArchitecture\ISO\" -recurse
 copy-item "C:\Program Files\Windows Kits\8.0\Assessment and Deployment Kit\Deployment and Imaging Tools\$OSArchitecture\Oscdimg\etfsboot.com" "c:\PE\winpe_$OSArchitecture\"

}

Function JBMURPHY-WinPE-2Mount{
	Param($OSArchitecture="x86",$WimFile="c:\PE\winpe_$OSArchitecture\ISO\sources\boot.wim")
	DISM.exe /Mount-Wim /WimFile:$WimFile /index:1 /MountDir:C:\PE\winpe_$OSArchitecture\mount
}

Function JBMURPHY-WinPE-3.0AddPAckages{
	Param($OSArchitecture="x86",$WimFile="c:\PE\winpe_$OSArchitecture\ISO\sources\boot.wim")
	$OCsPATH="C:\Program Files\Windows Kits\8.0\Assessment and Deployment Kit\Windows Preinstallation Environment\$OSArchitecture\WinPE_OCs"
	dism /image:C:\PE\winpe_$OSArchitecture\mount /add-package /packagepath:"$OCsPATH\WinPE-Scripting.cab"
	dism /image:C:\PE\winpe_$OSArchitecture\mount /add-package /packagepath:"$OCsPATH\en-us\WinPE-Scripting_en-us.cab"
	dism /image:C:\PE\winpe_$OSArchitecture\mount /add-package /packagepath:"$OCsPATH\WinPE-WMI.cab"
	dism /image:C:\PE\winpe_$OSArchitecture\mount /add-package /packagepath:"$OCsPATH\en-us\WinPE-WMI_en-us.cab"
	dism /image:C:\PE\winpe_$OSArchitecture\mount /add-package /packagepath:"$OCsPATH\WinPE-MDAC.cab"
	dism /image:C:\PE\winpe_$OSArchitecture\mount /add-package /packagepath:"$OCsPATH\en-us\WinPE-MDAC_en-us.cab"
	dism /image:C:\PE\winpe_$OSArchitecture\mount /add-package /packagepath:"$OCsPATH\WinPE-HTA.cab"
	dism /image:C:\PE\winpe_$OSArchitecture\mount /add-package /packagepath:"$OCsPATH\en-us\WinPE-HTA_en-us.cab"
	dism /image:C:\PE\winpe_$OSArchitecture\mount /add-package /packagepath:"$OCsPATH\WinPE-NetFx4.cab"
	dism /image:C:\PE\winpe_$OSArchitecture\mount /add-package /packagepath:"$OCsPATH\en-us\WinPE-NetFx4_en-us.cab"
	dism /image:C:\PE\winpe_$OSArchitecture\mount /add-package /packagepath:"$OCsPATH\WinPE-PowerShell3.cab"
	dism /image:C:\PE\winpe_$OSArchitecture\mount /add-package /packagepath:"$OCsPATH\en-us\WinPE-PowerShell3_en-us.cab"
	dism /image:C:\PE\winpe_$OSArchitecture\mount /add-package /packagepath:"$OCsPATH\WinPE-DismCmdlets.cab"
	dism /image:C:\PE\winpe_$OSArchitecture\mount /add-package /packagepath:"$OCsPATH\en-us\WinPE-DismCmdlets_en-us.cab"
}

Function JBMURPHY-WinPE-5UnMount-NoCommit{
	Param($OSArchitecture="x86",$WimFile="c:\PE\winpe_$OSArchitecture\ISO\sources\boot.wim")
	DISM.exe /unmount-Wim /MountDir:C:\PE\winpe_$OSArchitecture\mount /discard
}
Function JBMURPHY-WinPE-5UnMount{
	Param($OSArchitecture="x86",$WimFile="c:\PE\winpe_$OSArchitecture\ISO\sources\boot.wim")
	DISM.exe /unmount-Wim /MountDir:C:\PE\winpe_$OSArchitecture\mount /Commit
}

Function JBMURPHY-WinPE-6MakeISO {
	Param($OSArchitecture="x86",$WimFile="c:\PE\winpe_$OSArchitecture\ISO\sources\boot.wim")
	$command="C:\Program Files\Windows Kits\8.0\Assessment and Deployment Kit\Deployment and Imaging Tools\$OSArchitecture\Oscdimg\oscdimg.exe"
	&$command  -n -bc:\PE\winpe_$OSArchitecture\etfsboot.com c:\PE\winpe_$OSArchitecture\ISO c:\PE\winpe_$OSArchitecture\winpe_$OSArchitecture.iso
}

I have not tried this on x64, but I think you would need to pass -OSArchitecture amd64 to each function . Is it me or does Microsoft flip-flop between x64 and amd64 naming conventions?

Specifying Firefox setting (like proxy) on a machine across the enterprise.

We are interested in how to “push” proxy settings for Firefox across the environment. There are custom builds that claim to work with Group policy, but I wanted to manage the standard Firefox. A little digging shows that you need to create 2 files.

First, a file named mozilla.cfg and place it in “C:\Program Files\Mozilla Firefox”. This file contains the setting you want to “Set”/Lock down. For example:

//
lockPref(“network.proxy.type”, 1);
lockPref(“network.proxy.http”, “poxyserver.domain.com”);
lockPref(“network.proxy.http_port”, 80)

Second you place a file named “local-setting.js” in “C:\Program Files\Mozilla Firefox\defaults\pref”. The contents of that file would be something like this:

pref(“general.config.obscure_value”, 0); // only needed if you do not want to obscure the content with ROT-13
pref(“general.config.filename”, “mozilla.cfg”);

Here is some PowerShell code to create these files.

echo 'pref("general.config.obscure_value", 0);' >> "C:\Program Files\Mozilla Firefox\defaults\pref\local-etting.js"
echo 'pref("general.config.filename", "mozilla.cfg');' >> Out-File -filepath "C:\Program Files\Mozilla Firefox\defaults\pref\local-etting.js"
echo '//' >> "C:\Program Files\Mozilla Firefox\mozilla.cfg"
echo 'lockPref("network.proxy.type", 1);' >> "C:\Program Files\Mozilla Firefox\mozilla.cfg"
echo 'lockPref("network.proxy.http", "poxyserver.domain.com");' >> "C:\Program Files\Mozilla Firefox\mozilla.cfg"
echo 'lockPref("network.proxy.http_port", 80);' >> "C:\Program Files\Mozilla Firefox\mozilla.cfg"

Quick PowerShell script to run a command on every machine in an OU

I wanted to run a command on all machines in an OU. I know this documented all over the place, but this is the syntax I like:

foreach ($COMPUTER in $(Get-ADComputer -Filter * -Searchbase 'OU=SubOU,OU=TopLevelOU,DC=DOMAIN,DC=LOCAL')){
  write-host "Connecting to $($COMPUTER.Name)"
  Invoke-Command $COMPUTER.Name {ipconfig /renew}
}

Install OpenManage Server Administrator on ESXi5 via PowerCLI

Dell has changed how you install OpenManage Server Administrator on ESXi5. To do this via PowerCLI, use the following steps.

  1. Download the new vib file: OM-SrvAdmin-Dell-Web-6.5.0-542907.VIB-ESX50i_A02.zip (most recent can be found here)
  2. Extract it and upload the folder via the vSphere client (browse datastore and upload the extracted folder)
  3. Put the ESXi5 box into maintenance mode.
  4. From PowerShell with the PowerCLI installed:
    1. Connect- VIServer -Server x.x.x.x
    2. Install-VMHostPatch -HostPath /vmfs/volumes/datastore1/OM-SrvAdmin-Dell-Web-6.5.0-542907.VIB-ESX50i_A02/metadata.zip (or where ever you uploaded it)

Note: You can no longer connect directly to that web interface on port 1311 of the ESXi5 box. Now, you now have to go to a different OpenManage Server Administrator install (log out if you are auto logged in) and select “Manage remote node”. That is a pain.

jbmurphy.com’s first year in blogging


I had a goal last year, a goal of blogging 2 times a week for the entire year. I ended up with 116 posts. A couple of those posts were a few dates late, so I did not meet my exact goal of 2 times week, but I always managed 4 posts in every two weeks. My year end results are 16,368 visits and 14,067 unique visitors. Fun stuff.  I know is it no much, but I see a upward trent in the graph below! Wonder where I will be next year?

I hope my tech ramblings are useful to the 14,067 people that visited my site.

SQL query to find the number of WordPress posts this year!

I was compiling my year end wrap up (hits, posts, twitter followers), and I realized I did not know how many posts I created this year. I ran the following query again my WordPress database to find out.

select post_date,post_title from wp_posts where post_type = ‘post’ AND post_status = ‘publish’ AND post_date like ‘%2011-%’;

My goal was 2 a week for a year. I ended up with 116.

More on this later.

Powered by WordPress. Designed by WooThemes