Showing posts with label Windows 7. Show all posts
Showing posts with label Windows 7. Show all posts

Wednesday, October 14, 2015

PowerShell: Remove Windows 7 Telemetry Updates (Windows 10 Privacy Issue)

Windows 10 is violating user privacy.  Microsoft is retrieving too much personalized information about each person using Windows 10.  They've also created similar privacy violating security patches for Windows 7.  The following is a PowerShell script I created to remove the violating "security updates."

#Retrieve all Windows updates
$updates = wmic qfe list /format:csv|convertfrom-csv

#Search through update list and remove each violating update
if ($updates.hotfixid -like "*2990214*"){start-process "c:\windows\system32\wusa.exe" -wait -nonewwindow -argumentlist "/uninstall /kb:2990214 /norestart"}

if ($updates.hotfixid -like "*2952664*"){start-process "c:\windows\system32\wusa.exe" -wait -nonewwindow -argumentlist "/uninstall /kb:2952664 /norestart"}

if ($updates.hotfixid -like "*3021917*"){start-process "c:\windows\system32\wusa.exe" -wait -nonewwindow -argumentlist "/uninstall /kb:3021917 /norestart"}

if ($updates.hotfixid -like "*3022345*"){start-process "c:\windows\system32\wusa.exe" -wait -nonewwindow -argumentlist "/uninstall /kb:3022345 /norestart"}

if ($updates.hotfixid -like "*3035583*"){start-process "c:\windows\system32\wusa.exe" -wait -nonewwindow -argumentlist "/uninstall /kb:3035583 /norestart"}

if ($updates.hotfixid -like "*3068708*"){start-process "c:\windows\system32\wusa.exe" -wait -nonewwindow -argumentlist "/uninstall /kb:3068708 /norestart"}

if ($updates.hotfixid -like "*3075249*"){start-process "c:\windows\system32\wusa.exe" -wait -nonewwindow -argumentlist "/uninstall /kb:3075249 /norestart"}

if ($updates.hotfixid -like "*3080149*"){start-process "c:\windows\system32\wusa.exe" -wait -nonewwindow -argumentlist "/uninstall /kb:3080149 /norestart"}

#End of Script

If you want to automate the hotfix removal process, add a "/quiet" to the argumentlist.  For example: 
if ($updates.hotfixid -like "*3080149*"){start-process "c:\windows\system32\wusa.exe" -wait -nonewwindow -argumentlist "/uninstall /quiet /kb:3080149 /norestart"}

Each security update found will pop-up this first window:

Then it will prompt you to confirm the removal of the update:

Lastly, it removes the update:









After running this script, you'll need to restart your computer. Ensure to hide these updates when Windows Updater wants to add them back into your computer.

Monday, November 25, 2013

CMD: Install Windows 7 IP-based Printers via batch file

IT Departments debate over Server-based and IP-based direct printing.  I use IP-based printing as a way to lower WAN traffic, negate at least two points of failure, and speedup user response/print time.  Microsoft has developed some fine printer scripts they introduced in Windows XP.  They further polished these scripts in Windows 7 and placed them into their own printing_admin_scripts subfolder.  I'm sharing my sample script and giving a quick explanation of each command.  For more details about the Microsoft VB script switches, visit Microsoft's TechNet site or use Notepad to read the syntax notes placed inside each VBS file.

REMARK                   --- Start of Script ---

REMARK Added a script title so I know what printer I'm installing

echo *** Installing Canon iPF720 Plotter ***

REMARK Remove old printer presence via PowerShell registry search

PowerShell "if (test-path 'hklm:\software\microsoft\windows NT\currentversion\Print\Printers\HP DesignJet 1050C Plotter'){cscript c:\windows\system32\printing_admin_scripts\en-us\prnmngr.vbs -d -p 'HP DesignJet 1050C Plotter'}"

REMARK Checking for processor type then installing appropriate driver
REMARK AMD64 works with all typical Windows useable 64-bit processors

if %processor_architecture% equ AMD64 (cscript c:\windows\system32\printing_admin_scripts\en-us\prndrvr.vbs -a -m "Canon iPF720" -h "\\server\share\Printers\Drivers\Canon iPF720\64-bit\Driver" -i "\\server\share\Printers\Drivers\Canon iPF720\64-bit\Driver\6WJF02M.INF") else (cscript c:\windows\system32\printing_admin_scripts\en-us\prndrvr.vbs -a -m "Canon iPF720" -h "\\server\share\printers\Drivers\Canon iPF720\Driver" -i "\\server\share\printers\Drivers\Canon iPF720\Driver\2WJF02M.INF")

REMARK Adding the IP port the new printer will use

cscript c:\windows\system32\printing_admin_scripts\en-us\prnport.vbs -a -r "CanoniPF720" -h 192.168.1.100 -o raw -n 9100

REMARK Putting the Friendly name, driver, and port together

cscript c:\windows\system32\printing_admin_scripts\en-us\prnmngr.vbs -a -p "Canon iPF720 Plotter" -m "Canon iPF720" -r "CanoniPF720" 

REMARK Added a 10 second pause so I can chain install scripts together yet still monitor each installation progress

timeout /t 10

REMARK                   --- End of Script ---

I also thought about adding an audible prompt when things go right or wrong.  This would lessen the need to physically watch the install but rather allow multitasking by listening out for the correct sounds after each install while performing other duties.

Monday, February 18, 2013

PowerShell: Invoke-RestMethod, API's, and your music collection

Gathering ID3 tag information for your music files has become easier by embracing PowerShell 3's Invoke-RestMethod (IRM) command.  Many online databases use Application Programming Interfaces (API's) for developers to access their information.  These API's used to use XML but now have moved to the JSON language. IRM embraces JSON and allows us to create these API connections and query information about our music files.  In this article, I'm accessing Discogs Creative Commons open-source database.
Original Extended File Information
Updated after IRM and Discog's API

In my earlier article, I explained how to access shell.application in order to retrieve the extended file properties we use to rename and organize our files.  Combined with this method, we'll grab the extended file information and use it to find the correct file information and insert it into our files.  One point to make is that the API wants exact query information.  You'll receive no information if searching for an artist name of Quean instead of Queen.

 Syntax for Discogs allows us to search for song titles, artist names or IDs, album names and their release data plus much more.  The following demonstration script is fragile and incomplete.  It's to show how we embrace the power of PowerShell 3's Invoke-RestMethod.  Become familiar with IRM and API's to pull in online information into your scripts. It'll enhance the CURRENT information you're capable of accessing.  I'm really liking PS3's capabilities.

Disclaimer: Use this script at your own risk!  You'll be accessing Discogs live database and manipulating your computers music files.  This script uses the Windows 7 extended file information numbers.

##Start Script

$shell = new-object -com shell.application
$dirname = (get-item .\).fullname

#A quick and dirty way to find a song to use.  Run your script from your music folder

gi .\*.mp3
write "Type the exact (case-sensitive) song title you wish to query"
$fileinput read-host
$filename = gi .\$fileinput.mp3|?{(!($_.psiscontainer))}|foreach-object{$_.name}
$shellfolder = $shell.namespace($dirname).parsename($filename)

#now you can retrieve the extended file information and use those objects for your queries

$songtitle = $shell.namespace($dirname).getdetailsof($shellfolder,21)
$contribartist = $shell.namespace($dirname).getdetailsof($shellfolder,13)
$albumartist = $shell.namespace($dirname).getdetailsof($shellfolder,217)
$album = $shell.namespace($dirname).getdetailsof($shellfolder,14)
$genre = $shell.namespace($dirname).getdetailsof($shellfolder,16)
$year = $shell.namespace($dirname).getdetailsof($shellfolder,15)
$track = $shell.namespace($dirname).getdetailsof($shellfolder,26)
$length = $shell.namespace($dirname).getdetailsof($shellfolder,27)
$bitrate = $shell.namespace($dirname).getdetailsof($shellfolder,28)
$conductors = $shell.namespace($dirname).getdetailsof($shellfolder,17)
$bpm = $shell.namespace($dirname).getdetailsof($shellfolder,218)
$composers = $shell.namespace($dirname).getdetailsof($shellfolder,219)

#An example of how to replace spaces for your online queries. %20 is the variable used for space.

$apicontribartist = $contribartist -replace (' ','%20')
$apisongtitle = $songtitle -replace (' ','%20')

#Every artist in their database has an ID.  We query to find the ID.

$artistid = (irm http://api.discogs.com/artist/$apicontribartist).resp.artist.id

#We use the Artist ID to find the song's original release date.  Master is the keyword for original recording.

if ((invoke-restmethod http://api.discogs.com/database/search?artist=$artistid"&"type=master"&"title=$songtitle).results){
$origdate = ((invoke-restmethod http://api.discogs.com/database/search?artist=$artistid"&"type=master"&"title=$songtitle).results.resource_url|select -unique -first 1|%{invoke-restmethod $_}).year}else{
$origdate = ((invoke-restmethod http://api.discogs.com/database/search?artist=$apicontribartist"&"track=$songtitle).results.year)|sort|select -first 1}

#Locate Original Album hosting the audio track by using the 
#artist ID, releases, master, and date.

$master = ((irm http://api.discogs.com/artists/$artistid/releases).releases|?{$_.year -eq $origdate -and $_.type -eq "Master"})
$master = $master[0]
$origalbum = (irm $master.resource_url).title

#Now we can use the master album the song appeared on to find additional song information
#We find track number, released on Vinyl, 45, CD, etc., and I like to combine the styles and genres 
#& is a reserved PowerShell character.  We wrap it "&" so it will be passed to Discogs.

$origtracknumber = 1 + (((irm ((irm http://api.discogs.com/database/search?artist=$apicontribartist"&"title=$origalbum"&"track=$songtitle"&"year=$origdate"&"type=master).results).resource_url).tracklist|?{$_.title -eq $songtitle}).position.count)
$origformat = ((irm http://api.discogs.com/database/search?artist=$apicontribartist"&"title=$origalbum"&"track=$songtitle"&"year=$origdate"&"type=master).results)
$origformat = ((irm http://api.discogs.com/database/search?artist=$apicontribartist"&"title=$origalbum"&"track=$songtitle"&"year=$origdate"&"type=master).results).label|select -first 1
$origstyles = (irm ((irm http://api.discogs.com/database/search?artist=$apicontribartist"&"title=$origalbum"&"track=$songtitle"&"year=$origdate"&"type=master).results).resource_url).styles
$origgenres = (irm ((irm http://api.discogs.com/database/search?artist=$apicontribartist"&"title=$origalbum"&"track=$songtitle"&"year=$origdate"&"type=master).results).resource_url).genres

#I combined the styles and genre information so I can create better
#future genre searches.

$origgenre = ($origstyles + $origgenres)|sort

#write the updates back to the original file
#Try taglib for inserting tags back into your audio file.
#Here's a site which goes over some of its abilities.
#For Windows 7, when you download taglib, find the taglib-sharp.dll
#file, right-click it, select properties, and "unblock" it so you can load 
#the DLL into your ref.assembly command

$taglib = "c:\powershell\taglib\libraries\taglib-sharp.dll"
[system.reflection.assembly]::loadfile($taglib)
$tags = [taglib.file]::create($filename)

#type $tags to see the file properties
#type $tags.tag to see the extended file properties
#I'll let you take it from here :-)
##End Script




Friday, February 15, 2013

PowerShell: Clean & Manage Music Files

Disclaimer: USE THIS AT YOUR OWN RISK! This script is made for Windows 7!  There will be file renaming and moving so TEST, TEST, TEST.  You can test this script by copying one folder of music into an empty folder then run the script in that folder.  It will only process the files in that folder.  If all goes well, all files will move into a new folder structure named Music on your desktop.

To run this or any other PowerShell script, you'll have to read up on the Get-Executionpolicy and Set-Executionpolicy as PowerShell disables scripts by default.

My previous article explained how to clean the extra "stuff" added to music file names.  This article further cleans those file names, gets rid of the troublesome [brackets], then uses the Genre, Artist, and Album information to create a new folder structure on your desktop.  You can then move it to wherever you store your music.


Here is an example of some files my friend wanted help managing:

Notice the brackets, curly brackets, and other special characters in the file names and properties.


This is the same folder of music files after running the script:
I performed a search for all files to display the name changes.  Notice the subfolder structure that each file is located in.  The left side is the Genre structure created based on the file information.

Three more notes before going through the script:  

  1. The script automatically ignores subfolders.  I strongly recommend you perform this move one folder at a time so you can ensure it worked properly.
  2. The script will process any type of file.  You'll have to create an -exclude in the top $filename variable if you want it to ignore JPG's, AVI's, and etc.
  3. Do not save this script to the folder you are processing. It will be moved into the Music folder and could cause problems.
## Start of Script

#We call the Shell Object

$shell = new-object -com shell.application

#Organized Music Folder Location
#You can change the location. The Music Root Folder defaults to your desktop

$MusicFolder = ($home + '\desktop\music')

#remove brackets from filenames per PowerShells bug with brackets

gci .\* |?{(!($_.psiscontainer))}|foreach{move -literalpath $_ ($_.name -replace ('\[|]','~'))}

#Set directory and file variables.  Add -exclude to the Get-Item if you want 
#to ignore other filetypes
#For instance: (get-item .\* -exclude *.avi,*.jpg)

$dirname = (get-item .\).fullname
$filename = (get-item .\*)|?{(!($_.psiscontainer))}|foreach-object{$_.name}

foreach($file in $filename){

#original filename holder, then split it to capture the extension and name only.

$fileholder = $file
$ext = ('.' + ($file.split('.')[-1]))
$noext = $file.trimend($ext)

#get Title (item number 21) property from the file

$shellfolder = $shell.namespace($dirname).parsename($file)
$title = $shell.namespace($dirname).getdetailsof($shellfolder,21)

#PowerShell filename bug for brackets. 
#If there's a bracket in the title, $title will equal nul

if ($title -like "*``[*" -or $title -like "*``]*"){$title = $nul}

#if the title isn't empty, replace the filename with it

if ($title -gt 0){$file = ($title + $ext)}

#clean extraneous characters from the filename
#BTW, let me know if you have a better way to filter files
#for now, I borrowed this filter technique:

$file2 = $file -replace ('^[0-100]','')
$file3 = $file2 -replace ('.mp33','.mp3')
$file4 = $file3 -replace (' - ','-')
$file5 = $file4 -replace ('   ',' ')
$file6 = $file5 -replace ('  ',' ')
$file7 = $file6 -replace ('\(','')
$file8 = $file7 -replace (':','')
$file9 = $file8 -replace ('\)','')
$file10 = $file9 -replace ('\/','')
$file11 = $file10 -replace ('\>','')
$file12 = $file11 -replace ('\<','')

#Split the filename at the hyphen and only keep the last portion
#since that's normally the song name

$file13 = $file12.split('-')[-1]

$finalfilename = $file13

#rename the file after all the modifications

ren -erroraction silentlycontinue -path ($dirname + '\' + $fileholder) -newname $finalfilename

$shellfolder = $shell.namespace($dirname).parsename($finalfilename)

#Filtering for Artist - Items 13 and 217

$contribartist = $shell.namespace($dirname).getdetailsof($shellfolder,13)
$albumartist = $shell.namespace($dirname).getdetailsof($shellfolder,217)

#filtering the Album Name - Item 14

$album = $shell.namespace($dirname).getdetailsof($shellfolder,14)
$album1 = $album -replace ('^[0-100]','')
$album2 = $album1 -replace ('.mp33','.mp3')
$album3 = $album2 -replace (' - ','-')
$album4 = $album3 -replace ('   ',' ')
$album5 = $album4 -replace ('  ',' ')
$album6 = $album5 -replace ('\(','')
$album7 = $album6 -replace (':','')
$album8 = $album7 -replace ('\)','')
$album9 = $album8 -replace ('\/','')
$album10 = $album9 -replace ('\>','')
$album11 = $album10 -replace ('\<','')

$finalalbumname = $album11

#filtering the genre name - Item 16

$genre = $shell.namespace($dirname).getdetailsof($shellfolder,16)
$genre1 = $genre -replace ('^[0-100]','')
$genre2 = $genre1 -replace ('.mp33','.mp3')
$genre3 = $genre2 -replace (' - ','-')
$genre4 = $genre3 -replace ('   ',' ')
$genre5 = $genre4 -replace ('  ',' ')
$genre6 = $genre5 -replace ('\(','')
$genre7 = $genre6 -replace (':','')
$genre8 = $genre7 -replace ('\)','')
$genre9 = $genre8 -replace ('\/','')
$genre10 = $genre9 -replace ('\>','')
$genre11 = $genre10 -replace ('\<','')

$finalgenrename = $genre11

#Deciding between Album and Contributing artist then cleaning the name

$artist = if ($contribartist -gt 0){$contribartist}else{$albumartist}
$artist1 = $artist -replace ('^[0-100]','')
$artist2 = $artist1 -replace ('.mp33','.mp3')
$artist3 = $artist2 -replace (' - ','-')
$artist4 = $artist3 -replace ('   ',' ')
$artist5 = $artist4 -replace ('  ',' ')
$artist6 = $artist5 -replace ('\(','')
$artist7 = $artist6 -replace (':','')
$artist8 = $artist7 -replace ('\)','')
$artist9 = $artist8 -replace ('\/','')
$artist10 = $artist9 -replace ('\>','')
$artist11 = $artist10 -replace ('\<','')

$finalartistname = $artist11

$filetrim = $finalfilename.trimend($ext)
$filedupeinsert = ($filetrim + 'DUPE')
$filedupe = ($filedupeinsert + $ext)


#move file based on its Genre, Artist, and Album

#Replacing Brackets for tildes

if ($finalgenrename -like "*``[*" -or $finalgenrename -like "*``]*"){$finalgenrename -replace ('\[|]','~')}
if ($finalalbumname -like "*``[*" -or $finalalbumname -like "*``]*"){$finalalbumname -replace ('\[|]','~')}
if ($finalartistname -like "*``[*" -or $finalartistname -like "*``]*"){$finalartistname -replace ('\[|]','~')}

#moving songs to folders

#If there's no Genre entry, a default is used
#For the sake of endless genre possibilities, I used this filter to group
#the various types.  Manipulate as you see fit:

if ($finalgenrename -like "*Rock*"){$finalgenrename = "Rock"}
if ($finalgenrename -like "*Alt*"){$finalgenrename = "Alternative"}
if ($finalgenrename -like "*Metal*"){$finalgenrename = "Metal"}
if ($finalgenrename -like "*Pop*"){$finalgenrename = "Pop"}
if ($finalgenrename -like "*Rap*"){$finalgenrename = "Rap"}
if ($finalgenrename -like "*Hip*"){$finalgenrename = "Hip-Hop"}
if ($finalgenrename -like "*R&B*"){$finalgenrename = "R&B"}

if (!($finalgenrename -gt 0)){$finalgenrename = "Genre"}

#If there's no Album entry, a default is used

if (!($finalalbumname -gt 0)){$finalalbumname = "Album"}

#Creating the desktop\music folder structure
#and moving files to their new folders

if (!(dir $MusicFolder\$finalgenrename -erroraction silentlycontinue)){md $MusicFolder\$finalgenrename -force}
if (!(dir $MusicFolder\$finalgenrename\$finalartistname -erroraction silentlycontinue)){md $MusicFolder\$finalgenrename\$finalartistname -force}
if (!(dir $MusicFolder\$finalgenrename\$finalartistname\$finalalbumname -erroraction silentlycontinue)){md $MusicFolder\$finalgenrename\$finalartistname\$finalalbumname -force}
if (dir $MusicFolder\$finalgenrename\$finalartistname\$finalalbumname\$finalfilename -erroraction silentlycontinue){move -erroraction silentlycontinue ($dirname + '\' + $finalfilename) -destination $MusicFolder\$finalgenrename\$finalartistname\$finalalbumname\$filedupe}else{move -erroraction silentlycontinue ($dirname + '\' + $finalfilename) $MusicFolder\$finalgenrename\$finalartistname\$finalalbumname\$finalfilename -force}
}

## End of Script

Click Here to view the list of Windows 7 file properties you can access via shell.application.


Friday, February 8, 2013

PowerShell: Post-SysPrep scripts to Rename & Add Computer to Domain (using alternate credentials)


I tasked myself with the mission of using Microsoft's Windows 8 ADK to create a bootable Windows PE 4.0 UFD, and save a sysprepped workstation hard drive image (.wim) to the UFD. The UFD's WinPE boot sequence would have a PE-hooked batch file in which the user presses one button, walks away for 20 - 30 minutes and returns to a new PC which is on the Domain, in the correct OU, and has all its drivers loaded and GPO's applied.  The renaming and Domain adding portion of this process involved PowerShell's access to the win32_computersystem rename command and Add-Computer.

On my first attempt, I tried to rename the computer and add it to the domain during one boot. It just didn't work.  I had to reopen the pre-sysprep image and change the unattend.xml sysprep file's administrator login count from 1 to 2.  So the first boot checks then changes the computers name and places a RunOnce registry entry to kick off the second half of the process.  The second boot checks the computers name and if it is changed, grabs the IP address and starts a Add-Computer command associated with the OU of the corresponding IP subnet.

The PowerShell script during the first boot will create the computer name, add a regkey reboot hook, rename the computer, and restart it (it becomes passive during the second boot due to the computer name checks):

$ComputerName = ("Domain" + (gwmi win32_systemenclosure).SMBIOSAssetTag)

#A hook into the post-sysprep start script so it can be reran on next boot:

if ((gwmi win32_computersystem).name -ne $ComputerName){reg.exe add HKLM\Software\Microsoft\Windows\CurrentVersion\Runonce /v Restart /t REG_SZ /d "c:\scripts\start.bat" /f}

#Renaming the computer and restarting:

if ((gwmi win32_computersystem).name -ne $ComputerName){(gwmi win32_computersystem).rename($ComputerName);restart-computer}

#The second boot PowerShell script encrypts a domain user/pass, 
#determines the PC's IP subnet, then executes Add-Computer and 
#places the PC in the correct OU. Upon restart, kicks off GPUpdate at first Domain login.

#Saving the alternate Active Directory credentials:

$Username = "domain\delegateuser" 
$Password = convertto-securestring "secret" -asplaintext -force 
$Cred = new-object system.management.automation.pscredential($Username,$Password)

#Use ADSI to search for the computer object on the domain.  
#If one is found, add-computer with no OU is used.  If not then the script 
#finds the IP subnet and assigns the computers object to the appropriate OU


$searcher = [adsisearcher][adsi]""
$searcher.filter ="(cn=$ComputerName)"
$searchparm = $searcher.FindOne()
if (!($searchparm)){

#Checking the computer name then finding its IP subnet:

$ComputerName = ("Domain" + (gwmi win32_systemenclosure).SMBIOSAssetTag)
if ((gwmi win32_computersystem).name -ne $ComputerName){write "something went wrong with renaming the computer"|out-gr

idview;cmd /c pause}
$IP = [system.net.dns]::GetHostAddresses($env:computername)|?{$_.IPAddresstostring -like '192.168.*'}

#We've captured IP addresses to two octets and now find the 
#Active Directory Site via the third IP octet and perform the 
#add-computer command combined with the saved AD credentials and correct OU location:

if ($ip -like '192.168.0.*'){add-computer -domain MyDomain -Credential $cred -OUPath "OU=HQ,OU=WORKSTATIONS,DC=MyDomain,DC=COM"}
if ($ip -like '192.168.1.*'){add-computer -domain MyDomain -Credential $cred -OUPath "OU=Site1,OU=WORKSTATIONS,DC=MyDomain,DC=COM"}
if ($ip -like '192.168.2.*'){add-computer -domain MyDomain -Credential $cred -OUPath "OU=Site2,OU=WORKSTATIONS,DC=MyDomain,DC=COM"}

#closing the if statement concerning finding a computer object or not.
#The Else adds the computer to the domain and reattaching it to it's existing
#computer object

#Update 2/21/14
#I found it more efficient to take away the else statement and instead just create a catch-all:   add-computer -domain MyDomain -Credential $cred
#Another problem was re-imaging existing domain computers.  AD would try
#creating another GUID and cause GPO and other problems.  
#To fix this, I added:
start-process powershell.exe -credential $cred -argumentlist 'if (!(test-computersecurechannel)){test-computersecurechannel -repair}

#so if the computer is in the domain but not in one of the above mentioned subnets, it'll still be added to the domain.

}else{add-computer -domain MyDomain -Credential $cred}

#The computer is now a member of the Domain.  Next add a 
#Registry RunOnce key entry so the next boot will start a 
#forced application of GPUpdate relevant to it's OU:

reg.exe add HKLM\Software\Microsoft\Windows\CurrentVersion\Runonce /v GPUpdate /t REG_SZ /d "gpupdate /force" /f

Lastly, delete the scripts with passwords in them and restart the computer so it can change its network affiliation from WORKGROUP to the new Domain assignment:

reg.exe add HKLM\Software\Microsoft\Windows\CurrentVersion\Runonce /v DelPS1 /t REG_SZ /d "del c:\scripts*.ps1 /q" /f
restart-computer

This process works and has a positive side-effect: It stops the computer from joining the domain if the Computer Object already exists (which stops any sort of SID problems or unintended OU movements).

It's been suggested by a fellow Redditor that I should create a switch instead of the If statements breaking down the IP subnets.  I'll update this post after I've tested that portion.  Let me know if you have any questions, comments, or suggestions.

Monday, November 12, 2012

PowerShell: Resolve Remote Host and IPv4 Address

Update: I found the script block only works on local hosts.  As such, I found another way to get the remote host name and IP via PowerShellASP.

<%$ipaddress = [net.IPAddress]::Parse($request.UserHostAddress)%>

<%$UserHostname = [System.Net.Dns]::gethostentry($ipaddress.ipaddresstostring)%>
<%$UserHostname = $UserHostName.hostname -replace ".domain.suffix",""%>
Your Computers IP:<%=$ipaddress%> & Host Name:<%=$userhostname%><br><hr>

Click here to find your public IP address without using PowerShellASP.


I don't know if this helps but I've been working on a way to obtain the remote host name and IP for my PowerShellASP site.  Every several searches and testing, I found .net commands which extract the host name and an IPv4 adddress:
#PowerShell Script
$remotehostname = [system.net.dns]::gethostname()
#I noticed the ScopeID of IPv4 addresses is always $null, so I used that to find the IPv4 address
$remotehostipv4 = [system.net.dns]::gethostaddresses($remote)|?{$_.scopeid -eq $null}|%{$_.ipaddresstostring}
#Sample line displaying the host and IP.
$remotehostname,$remotehostipv4
Then I applied them to a test PowerShellASP file:



<%$remote = [system.net.dns]::gethostname()%>

<%$remoteip = [system.net.dns]::gethostaddresses($remote)|?{$_.scopeid -eq $null}|%{$_.ipaddresstostring}%>

Remote IP: <%=$remoteip%><br>
Remote: <%=$remote%>

By obtaining the remote host name and IP (a PowerShellASP website visiting computer), I can create a remote connection and run PowerShell commands on the remote host for the user.  By default, PowerShellASP will run all commands on the server, meaning that a request to see how much hard drive space is left will be ran on the server.  This will return the server's remaining hard drive space result to the remote user.  Frankly, the user doesn't care about the servers hard drives and really wants to know about their own hard drives.  To perform this request, the web server has to create a remote WMI connection and run the command. Having the remote host information allows this to happen.

Sunday, November 4, 2012

Virtual PC: Mounting a Windows 7 32-bit VM

The following is an overview of the Windows 7 Virtual Machine (VM) for Windows 7 Virtual PC creation process:
1. Download the AIK (MS Automated Installation Kit) with SP1.
2. Copy a file from the AIK to a hard drive with ample room for the VM.
3. Download and move a script which converts a Windows 7 install CD into a VHD.
4. Download and install Windows 7 Virtual PC.
5. Create a virtual machine.
6. Start the Windows 7 VHD virtual machine.
7. Install Windows 7 as normal.
8. Install the Integration Components.

Detailed Instructions:
1. Download the Automated Installation Kit; which is an ISO file.  ISO's are not normally readable by Windows so I used Slysoft's free virtual clone drive.  Slysoft's software will install a virtual DVD drive which shows up in the system tray with a new drive letter.



Right click on its system tray icon and "mount" the AIK.ISO file that you downloaded.  Let autorun start the AIK install or alternatively double-click on StartCD.exe.  Install the software.

2. Download the Automated Installation Kit Service Pack 1.  Mount the downloaded waik_supplement_en-us (or equiv).ISO and copy the contents into the AIK PETools folder (c:\program files\Windows AIK\Tools\PETools - if you used the defaults).
3. Download the Microsoft WIM2VHD.WSF script. Now you want to copy WIM2VHD.WSF to a large drive.  This will be the location where your new Windows 7 virtual drive will be created.  Also, go into c:\program files\windows AIK\Tools\ and copy imageex.exe (from the appropriate CPU-type subfolder) to the same drive as WIM2VHD.WSF.
4. Make your Windows 7 32-bit DVD/USB source accessible and run this command from an elevated command line (right-click cmd.exe runas-administrator) from the folder which has WIM2VHD.WSF and imageex.exe:
cscript wim2vhd.wsf /wim:d:\sources\install.wim /sku:{professional|enterprise|ultimate} 
note: d: - current Windows 7 install source location; sku type is Windows version (pick one).
 

5.  When the script successfully completes, it will create the VHD file and place it in the folder where you ran the script.  It will have a name similar to this:
(6.1.7600.16385.x86fre.win7_rtm.090713-1255.Enterprise.en-US.vhd)

6. Download Windows Virtual PC. You'll have to pass a Windows license verification authentication first.  Also, check your computer to ensure it can support a virtual machine.  Your BIOS and components have to possess this capability and download and run this Microsoft tool to test your computer.  After you have tested for compatibility and validated your license, install Windows Virtual PC.  You will have the choice of installing the 32 or 64 bit version.  For some reason, I can only use 32-bit virtual machines even though I have the 64-bit Virtual PC software.  I think it might be a software limitation.  Also, be aware that if you've disabled the Windows Update service, this software will be unable to install.

7.  From the Start Menu, open Windows Virtual PC.  Create a Virtual Machine and select your newly created VHD.  After creating the VM, click on Settings and review/alter the settings to suit your needs.



8.  Open the VM and you'll see it perform sysprep steps as it installs Windows 7 in your Virtual Machine.
9. When finished, it will act like a normal Windows installation and need anti-virus, security patches, and other normal utilities.
10.  Ensure to install the Integration Tools found on the VM's Tools menu.  This will allow you to move your mouse in and out of the VM without it being captured.  To break your mouse out of the VM, press the Windows keyboard key.


This blog entry based on information from:
http://forums.mydigitallife.info/archive/index.php/t-32822.html
http://www.hanselman.com/blog/StepByStepTurningAWindows7DVDOrISOIntoABootableVHD VirtualMachine.aspx

Friday, June 8, 2012

Windows 7 Icon Files

I read a frustrating article on TechRepublic about the locations of the icon files in Windows 7.  Every file location was in it's own picture with the associated icons.  The article was 16 pages long with unviewable icons.  Here is a one page viewable icon post:

Windows 7 icon files and their locations, with all of the icons from the listed files:
1. c:\windows\system32\shell32.dll
2. c:\windows\explorer.exe
3. c:\windows\system32\accessibilitycpl.dll
4. c:\windows\system32\ddores.dll
5. c:\windows\system32\gameux.dll
6. c:\windows\system32\imageres.dll
7. c:\windows\system32\moricons.dll
8. c:\windows\system32\mmcndmgr.dll
9. c:\windows\system32\mmres.dll
10. c:\windows\system32\netcenter.dll
11. c:\windows\system32\netshell.dll
12. c:\windows\system32\networkexplorer.dll
13. c:\windows\system32\pifmgr.dll
14. c:\windows\system32\pnidui.dll
15. c:\windows\system32\sensorscpl.dll
16. c:\windows\system32\setupapi.dll
17. c:\windows\system32\wmploc.dll
18. c:\windows\system32\wpdshext.dll

c:\windows\system32\DDORES.DLL
Top of Page
c:\windows\system32\ACCESSIBILITYCPL.DLLc:\windows\EXPLORER.EXEc:\windows\system32\GAMEUX.DLL



Top of Page


c:\windows\system32\IMAGERES.DLL

Top of Page
c:\windows\system32\IMAGERES.DLL

Top of Page
c:\windows\system32\MMCNDMGR.DLL

Top of Page
c:\windows\system32\MMRES.DLLc:\windows\system32\NETCENTER.DLL
Top of Page
c:\windows\system32\MORICONS.DLL

c:\windows\system32\NETSHELL.DLL

Top of Page
c:\windows\system32\NETSHELL.DLL

Top of Page
c:\windows\system32\NETWORKEXPLORER.DLLc:\windows\system32\WPDSHEXT.DLLc:\windows\system32\PIFMGR.DLLc:\windows\system32\SENSORSCPL.DLL

Top of Page
c:\windows\system32\PNIDUI.DLL

Top of Page
c:\windows\system32\SETUPAPI.DLL

Top of Page
c:\windows\system32\SHELL32.DLL

Top of Page
c:\windows\system32\SHELL32.DLL

Top of Page
c:\windows\system32\WMPLOC.DLL

Top of Page
c:\windows\system32\WMPLOC.DLL

Top of Page