Developer's Closet A place where I can put my PHP, SQL, Perl, JavaScript, and VBScript code.

26Feb/150
PowerShell script to convert string to encrypted password and back again

I've found it useful to store an encrypted password in a file on disk. However, this is not generally a good idea but at least the password is encrypted to the user/machine. Here is a rough outline of the process:

-- convert to encrypted password from clear text
$password = ConvertTo-SecureString 'SomePassword' -AsPlainText –Force
-- write to file as user/machine encrypted string which cannot be unencrypted by any other user on any other machine
$password|convertFrom-SecureString|set-content "c:\temp\cred.txt"
$password

 

To make the file really useable, preface the password with the username and query for the username:

-- query for user name from file

$username = "UserName";
-- convert password to a secure string that can be sent through to Windows for authentication
$password = Get-Content "c:\temp\cred.txt" | Select-String $Username | foreach{$_ -replace $Username, ""} | foreach{$_ -replace " ",""} | ConvertTo-SecureString;

 

Finally, you can go a step further and crack open the password:

-- convert from encrypted password to clear text
$Ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToCoTaskMemUnicode($password);
$password = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($Ptr);[System.Runtime.InteropServices.Marshal]::ZeroFreeCoTaskMemUnicode($Ptr);
$password
Filed under: PowerShell No Comments
4Aug/140
Useful Scripts

PowerShell:

$ou = [adsi]"LDAP://OU=Marketing,OU=Departments,DC=Company,DC=Domain";
$user = $ou.psbase.get_children().find('CN=UserName');
$user.psbase.invokeSet("allowLogon",0);
$user.setinfo();

Bash:

#!/bin/bash
fname="/path/file"
tname="/new/file.tmp"
i="0"
DATE=$(date +%Y%m%d%H%M%S)
sudo cp "$fname" "$fname".$DATE

while IFS='' read -r line
do
if [ "$line" == " line item:" ] || [ $i -gt 0 -a $i -lt 4 ]
then
echo -e "#$line" | sudo tee -a $tname
i=$(($i + 1))
else
printf "%s\n" "$line" | sudo tee -a "$tname"
fi
done <"$fname"

sudo mv $tname $fname

Batch:

$SourcePath = 'C:\Path\';
$DestServer = 'ServerName';
$DestPath = '/path/';
$FileName = 'FileName';
$Output = @()
$cmd = @(
"y",
"lcd $SourcePath",
"cd $DestPath",
"mput $FileName",
"quit"
)

$Output = $cmd | & "C:\Program Files (x86)\Putty\psftp.exe" –v $DestServer 2>&1;
$Err = [String]($Output -like "*=>*");
If (($LastExitCode -ne 0) || (($Err.Contains("=>")) -eq $false)) {
throw "File Failed to Transfer! `n $($Output)";
}

Linux:

sudo mkdir /space;
echo "/dev/space /space ext4 defaults 0 0" | sudo tee -a /etc/fstab;
sudo mount /dev/space /space;
sudo df -h;
ls /dev/;

PowerShell:

Add-PSSnapin Quest.ActiveRoles.ADManagement;
connect-QADService -service domain;
set-QADuser UserName -TSRemoteControl 0;
$objCurrentPSProcess = [System.Diagnostics.Process]::GetCurrentProcess();
Stop-Process -Id $objCurrentPSProcess.ID;

 

1Aug/130
Get All Installed Software Using PowerShell

The following PowerShell script will return all installed software on a Windows server.

function GetInstalledMSIVersionNumber($MSIName) {
	#Define the variable to hold the location of Currently Installed Programs
	$registry = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall","SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
	$Results = "";
	foreach($UninstallKey in $registry){
		$computername="ServerName";
		#Create an instance of the Registry Object and open the HKLM base key
		$reg=[microsoft.win32.registrykey]::OpenRemoteBaseKey('LocalMachine',$computername) 
		#Drill down into the Uninstall key using the OpenSubKey Method
		$regkey=$reg.OpenSubKey($UninstallKey) 
		#Retrieve an array of string that contain all the subkey names
		$subkeys=$regkey.GetSubKeyNames() 
		#Open each Subkey and use GetValue Method to return the required values for each
		foreach($key in $subkeys){
			$thisKey=$UninstallKey+"\\"+$key 
			$thisSubKey=$reg.OpenSubKey($thisKey) 
			if ($($thisSubKey.GetValue("DisplayName"))) {
				# header: DisplayName,DisplayVersion,Publisher,InstallDate,InstallLocation,InstanceId,UninstallString,EstimatedSize
				$Results = $Results + """" + $($thisSubKey.GetValue("DisplayName") + """" + "," + """" + $thisSubKey.GetValue("DisplayVersion") + """" + "," + """" + $thisSubKey.GetValue("Publisher") + """" + "," + """" + $thisSubKey.GetValue("InstallDate") + """" + "," + """" + $thisSubKey.GetValue("InstallLocation") + """" + "," + """" + $thisSubKey.GetValue("InstanceId") + """" + "," + """" + $thisSubKey.GetValue("UninstallString") + """" + "," + """" + $thisSubKey.GetValue("EstimatedSize") + """" + "`n");
			}
		} 
	}
	return $Results;
}
$Results = GetInstalledMSIVersionNumber("");
$Results;
10May/130
PowerShell Script to Recursively Zip All Files in Folder

I've enclosed a simple PowerShell script to recursively zip files using the built in shell. Works in PowerShell 2 and 3, no additional zip applications to install. I use this very useful script to tidy up a folder of trace files or backup files. To zip all files, remove the Include from the Get-ChildItem command.

# example: .\Zip-Recursively.ps1 c:\Temp\Test trc

$filePath = $args[0];
$Ext = $args[1];
if($filePath.Length -lt 3)
{
	Write-Host "Enter a path name as your first argument" -foregroundcolor Red
	return
}
if($Ext.Length -lt 1)
{
	Write-Host "Enter a file extension as your second argument" -foregroundcolor Red
	return
}
if(-not (Test-Path $filePath)) {
	Write-Host "File path does not appear to be valid" -foregroundcolor Red
	return
}
$files = Get-ChildItem $filePath -Include *.$Ext -recurse

foreach($file in $files) { 
	$fileZipName = $file.Name;

	if (-not $fileZipName.EndsWith('.zip')) {
		$fileZipName += '.zip'
	}

	$fullFilePath = $filePath + "\" + $fileZipName

	# Prepare the zip file
	set-content $fullFilePath ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))

	$shellApplication = new-object -com shell.application
	$zipPackage = $shellApplication.NameSpace($fullFilePath)

	$zipPackage.CopyHere($file.Fullname)

	# Checks each file to make sure it is added before moving to the next file
	while($zipPackage.Items().Item($file.name) -eq $null){
		Start-sleep -seconds 1
	}

	# Delete the file
	Remove-Item $file.Fullname ;

	$fullFilePath
}

10Apr/130
PowerShell Script Execution Policy

The Set-ExecutionPolicy cmdlet enables you to determine which PowerShell scripts will be allowed to run on your computer. PowerShell has four different execution policies:

  • Restricted - No scripts can be run. Windows PowerShell can be used only in interactive mode.
  • AllSigned - Only scripts signed by a trusted publisher can be run.
  • RemoteSigned - Downloaded scripts must be signed by a trusted publisher before they can be run.
  • Unrestricted - No restrictions; all Windows PowerShell scripts can be run.

For example:

Set-ExecutionPolicy Unrestricted

7Feb/130
Use PowerShell to Uninstall an Application – Comparing WMI vs. a Registry Scan

If you have ever scanned the list of currently installed programs using the WMI Win32_Product class, you've noticed that the scan runs slow! This always frustrates me. It seems that WMI attempts to reconfigure every installed product. Even the simplest query can take minutes to run. Here is an example:

$app = Get-WmiObject -Class Win32_Product -Filter "Name like '%\\iCloud\\%'";

On my workstation, this query took over two minutes to complete. A quick check of the events in my Application Event Log shows over 300 events from MsiInstaller with a message similar to this one: Windows Installer reconfigured the product. Add an uninstall command to uninstall iCloud:

$app = Get-WmiObject -Class Win32_Product -Filter "Name like '%\\iCloud\\%'";$app.Uninstall() | out-string;

There is a faster way to search for an installed application. The  registry key Uninstall contains all installed applications.

set-location HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall;$Results = Get-ChildItem | foreach-object { $_.GetValue("DisplayName") }

All currently installed applications will be displayed. Fast huh? Put this registry scan along with WMI uninstall, and you can uninstall any MSI using PowerShell very quickly. The function was pieced together from a few sources online, the most helpful was Use PowerShell to Find and Uninstall Software. Here is the function:

function UninstallInstalledMSI($MSIName) {
	$Results = "";
	if ((!$MSIName) -or ($MSIName.TrimEnd() -eq "")) { return $false; }
	#Define the variable to hold the registry paths used by 32 and 64 bit
	$registry = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall","SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
	foreach($UninstallKey in $registry){
		$computername="SERVERNAME";
		#Create an instance of the Registry Object and open the HKLM base key
		$reg=[microsoft.win32.registrykey]::OpenRemoteBaseKey('LocalMachine',$computername) 
		#Drill down into the Uninstall key using the OpenSubKey Method
		$regkey=$reg.OpenSubKey($UninstallKey) 
		#Retrieve an array of string that contain all the subkey names
		$subkeys=$regkey.GetSubKeyNames() 
		#Open each Subkey and use GetValue Method to return the required values for each
		foreach($key in $subkeys){
			$thisKey=$UninstallKey+"\\"+$key 

			$thisSubKey=$reg.OpenSubKey($thisKey) 

			if ($($thisSubKey.GetValue("DisplayName")) like '%$MSIName%') {

				$classKey="IdentifyingNumber=`"$key`",Name=`"$($thisSubKey.GetValue("DisplayName"))`",version=`"$($thisSubKey.GetValue("DisplayVersion"))`"";
				$Results += ([wmi]"Win32_Product.$classkey").uninstall() | out-string;

			}
		} 
	}
	return $Results;
}
$Results = UninstallInstalledMSI("iCloud");if($Results) { $Results; }


31Jan/130
PowerShell command to check if a directory exists and if not, create it

I often have to look up this simple PowerShell command. The following command checks if a folder exists and if not, creates it. Works great.

if ((Test-Path -path C:\Temp\Folder\) -ne $True) { New-Item C:\Temp\Folder\ -type directory; }

14Jan/130
Use PowerShell to list all property values from a registry entry

I've had to use a variation of this script many times and each time I've been stumped for 30 minutes before coming to a solution. Microsoft has not addressed this issue very well with the Get-ItemProperty cmdlet, so the Select-Object is necessary. Without further fanfare, here is a script to list the property values from a registry entry:

Set-Location 'HKCU:\Software\Microsoft\Assistance\Client\1.0\Settings'
Get-Item . |
Select-Object -ExpandProperty property |
ForEach-Object {
New-Object psobject -Property @{"property"=$_;
"Value" = (Get-ItemProperty -Path . -Name $_).$_}} |
Format-Table property,value -AutoSize

Add -HideTableHeaders to Format-Table to remove the header. Remove the property header from Format-Table to view only values.

Filed under: PowerShell No Comments
9Nov/120
Study an Exception in PowerShell

PowerShell may not return enough information in an exception. You can read the response stream to dig deeper:

$stream = new-object System.IO.StreamReader($Error[0].Exception.InnerException.Response.GetResponseStream())
$results = $stream.ReadToEnd()
$results
$stream.Close()

The results should be more descriptive than the exception.

 

30Oct/120
PowerShell String to Array to a Foreach Loop

I always forget to use the Split command (or write it in VBScript before I remember PowerShell). The following command takes a comma separated list (string), and splits the string into an array. Then loop through the array in a foreach loop:

$list = "1,2,3,4";
$lists = $list.split(",");
foreach($l in $lists){ $l }

That's easy enough to remember. To access any item from the list, you can simply print: $lists[0]