Showing posts with label Command Line. Show all posts
Showing posts with label Command Line. Show all posts

Sunday, May 22, 2016

PowerShell & SCCM 2012: Get Old Computer SCCM Software Packages, add more software, and Export CSV out for New Computer

Using PowerShell and WMI to access the SCCM server, this post shows how to transfer a software list from the old computer and export it for the new one. In another post I describe how to automate the new computers software package collection addition process after its registered itself with the SCCM server and installed the SCCM client software.

$SCCMserver = SCCMServer01
$namespace = "root\sms\site_xx1"
$adminname = "Domain\AdmUser"
$password = get-content .\adminpassword.txt|convertto-securestring -key (1..16)
$admcred = new-object system.management.automation.pscredential($adminname,$password)
$i = 0

$OldComputerSoftware = Get-WmiObject -Namespace $namespace -Class SMS_fullcollectionmembership -ComputerName $SCCMServer -filter "Name = '$SCCMoldcomputer'" -credential $admcred
$OldComputerCollectionMemberList = $CollectionList|? {$OldComputerSoftware.collectionID -contains $_.collectionID}

Above I declare my variables, query the SCCM server for all the software on the old computer, and compare it to the $CollectionList collections filtering array. Next I create $NewPCSoftwareList using the old computer software list. Add line numbers and filter unwanted collections via $XList. The $AddedSoftware variable displays the existing software from the old computer and will be updated with software selections in the read-host menu below:

$NewPCSoftwareList = $OldComputerCollectionMemberList|select Name,CollectionID
foreach ($C in $NewPCSoftwareList){$i++;$C|add-member -notepropertyname line -notepropertyvalue $i}
$NewPCSoftwareList = $NewPCSoftwareList|? {$xlist.name -notcontains $_.name}
$addedsoftware = $collectionlist|? {$NewPCSoftwareList.name -contains $_.name}


Available SCCM Software Packages
 1 Adobe Acrobat Pro
 2 Adobe Acrobat Standard
 3 Base Camp
 5 Topography Software
 6 Google Earth Pro
 7 Windows Mobile Device Center

OldComputerName SCCM Software will be installed on NewComputerName 

 4 7-Zip
 8 Microsoft Office 2013

Enter line number to add SCCM software to NewComputerName
Enter DONE if satisfied with install list
(Line number or Done): _


do{
cls
write-host "Available SCCM Software Packages" -f white
$collectionlist|? {$InstalledSoftwareList.name -notcontains $_.name}|format-table line,name
write-host "SCCM Software already installed on $computername" -f white
$InstalledSoftwareList|format-table line,name -hidetableheaders
if ($newsoftware){
write-host "Software to be added" -f yellow
$newsoftware|format-table line,name -hidetableheaders

}
write-host "Enter " -nonewline;write-host "line number" -f white -nonewline;write-host " to add SCCM software to $computername"
write-host "Enter " -nonewline;write-host "DONE" -f white -nonewline;write-host " if satisfied with install list"
$addpackages = read-host "(Line number or Done)"
if ($addpackages -ne "done"){
$newsoftware += $collectionlist|? line -eq $addpackages
}
} while ($addpackages -ne "done")
The starting menu displays the full available software list minus those software already pre-selected to be added to the new computer. I input the number for each additional software I want added to the new computer then type DONE when finished adding software. Note that the line numbers disappear from the top list when selected on the bottom one. After DONE is typed, the $addedsoftware array gets exported to a CSV that the new computer will access in order to install that software. That part of the process will be in another post.

if ($addedsoftware){$addedsoftware|export-csv .\NewComputerName-SCCMsoftware.csv}

PowerShell & SCCM 2012: Retrieving and Filtering Collections

In order to expedite my computer replacement process, I decided to automate the software transfer from the old computer to the new one. This post goes over the first part of that process. I thank the many great people that have posted how to retrieve information from SCCM via WMI. I built upon their success and customized it for my needs. In this first snippet, I declare my variables, poll the SCCM server, then query the SCCM server for all its collections ($CollectionList). I also import my collection filtering CSV file ($xlist).

$SCCMserver = SCCMServer01
$namespace = "root\sms\site_xx1"
$adminname = "Domain\AdmUser"
$password = get-content .\adminpassword.txt|convertto-securestring -key (1..16)
$admcred = new-object system.management.automation.pscredential($adminname,$password)
$i = 0

if (test-connection $SCCMServer){
$xlist = import-csv \\server\share\SCCMscripts\CollectionFilter.csv
$CollectionList = get-wmiobject -query "Select * from SMS_Collection" -namespace $namespace -computername $SCCMserver -credential $admcred
$CollectionList = $CollectionList|? {$xlist.name -notcontains $_.name}
foreach ($C in $CollectionList){$i++;$C|add-member -notepropertyname line -notepropertyvalue $i}
}

With the above, I've filtered through the complete collection list using my collection filtering CSV, added a new array property named line, and have run the resulting list through a line numbering loop so I can present the collection list for further filtering as in the example below.

Available SCCM Software Packages
 1 Adobe Acrobat Pro
 2 Adobe Acrobat Standard
 3 7 Zip
 4 Google Earth
 5 AutoCAD LT

Enter software package line number to remove from availability list
Enter NONE if no changes are needed
(Line number or NONE:): 5
Available SCCM Software Packages - Updated
 1 Adobe Acrobat Pro
 2 Adobe Acrobat Standard
 3 7 Zip
 4 Google Earth

Enter software package line number to remove from availability list
Enter NONE if no changes are needed
(Line number or NONE:): NONE

In the above example, my filtered $CollectionList displayed five software packages. I typed in number 5 to remove AutoCAD LT from my software list, press Enter, and the list now only has the four remaining packages. Once finished updating the software list, I will use the filtered list to apply against the old computer's software list. This helps me select software for its replacement without wading through all the other arbitrary collections and packages. I'll show that software selection process in another post.

do{
if (!($remove)){write-host "Available SCCM Software Packages" -f white}
if ($remove){write-host "Available SCCM Software Packages" -f white -nonewline;write-host " - Updated" -f green}
$CollectionList|format-table line,name -hidetableheaders
write-host "Enter software package " -nonewline;write-host "line number" -f white -nonewline;write-host " to remove from availability list"
write-host "Enter " -nonewline;write-host "NONE" -f white -nonewline;write-host " if no changes are needed"
$addtoxlist = read-host "(Line number or NONE)"
if ($addtoxlist -ne "none"){
[array]$remove += $CollectionList|? line -eq $addtoxlist|select name,collectionID
$CollectionList = $CollectionList|? {$remove.name -notcontains $_.name}
}
} while ($addtoxlist -ne "none")

After "None" is typed, the $remove list is applied to $xlist then exported back out to the filter list.

if ($remove){
$xlist = $xlist|select Name,CollectionID #removing the line number object
$xlist += $remove|select Name,CollectionID #adding the selected collection items to the filter list
$xlist = $xlist|sort CollectionID -unique #removing duplicate entries
$xlist|export-csv \\server\share\SCCMscripts\CollectionFilter.csv}

Thursday, April 16, 2015

PowerShell: Box.com Drive Mapping via DAV

Thanks to a couple of web articles I found (1,2), I'm now able to connect to my Box.com account as a drive letter.

tl;dr:
net use b: \\dav.box.com@SSL\dav /u:boxuser boxpassword

Whole script:
$password = "your embedded & encrypted Box password"

$pscred = New-Object PSCredential -ArgumentList "yourboxaccount@mail.com", ($password | ConvertTo-SecureString)

#Checking if a DAV connection exists and if not, then creating one and assigning it Drive B:

if (get-psdrive|? {$_.currentlocation -like "Your Box Root Folder\Some Box Subfolder*"}){$drive = get-psdrive|? {$_.currentlocation -like "Your Box Root Folder\Some Box Subfolder*"}|select -expandproperty root}else{net use b: \\dav.box.com@SSL\dav /u:yourboxaccount@mail.com $pscred.getnetworkcredential().Password;$drive = "B:\"}

Now you can use Robocopy instead of "Box Sync" to sync your Box.com data:
robocopy "\\server\share\content" ($drive + "Your Box Root Folder\Some Box Subfolder") /s /e /v
robocopy ($drive + "Your Box Root Folder\Some Box Subfolder") "\\server\share\content" /s /e /v

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




Monday, February 11, 2013

PowerShell: Creating & Deleting Outlook 2003-2010 Appointments

I wanted to help my finance department set up meeting reminders that most staff need on their calendars.  We couldn't find a way to create an Outlook Recurring Event since the dates varied from month to month.  For lack of an easier way to automate the decimation of these meeting reminders via Outlook, I turned to a PowerShell solution.  I found several articles and two stood out: Richard Siddaway's Delete Items blog entry and the Hey, Scripting Guys Export Calendar blog.  Using bits from both as well as other locations, I created a simple way to add and delete Calendar Appointments.


Creating Outlook Calendar Appointments


#The first two lines connect to Outlook and prepare for the new item entries

$olAppointmentItem = 1 

$o = new-object -comobject outlook.application 

#Each new calendar appointment must have the CreateItem and Save lines

#--------One complete Calendar---------------
$a = $o.CreateItem($olAppointmentItem) 
  
$a.Start = "2/14/2013 8:00 AM" 
$a.Duration = 60 
$a.Subject = "Monthly Budget Meeting" 
$a.Body = "See Agenda Items at http://www.contoso.com" 
$a.Location = "Finance Section" 
$a.ReminderMinutesBeforeStart = 15 
$a.ReminderSet = $True 
  
$result = $a.Save() 
#--------Appointment Item Entry--------------

$a = $o.CreateItem($olAppointmentItem) 
  
$a.Start = "3/11/2013 8:00 AM" 
$a.Duration = 60 
$a.Subject = "Monthly Budget Meeting" 
$a.Body = "See Agenda Items at http://www.contoso.com" 
$a.Location = "Finance Section" 
$a.ReminderMinutesBeforeStart = 15 
$a.ReminderSet = $True 
  
$result = $a.Save() 

$a = $o.CreateItem($olAppointmentItem) 
  
$a.Start = "4/18/2013 8:00 AM" 
$a.Duration = 60 
$a.Subject = "Monthly Budget Meeting" 
$a.Body = "See Agenda Items at http://www.contoso.com" 
$a.Location = "Finance Section" 
$a.ReminderMinutesBeforeStart = 15 
$a.ReminderSet = $True 
  
$result = $a.Save() 

#End of Script, you've now added three appointments. 
#Expand to suit your needs and add/delete $a. fields as needed.


Deleting Outlook Calendar Appointments


#Connect to Outlooks Calendar Folder System

Add-type -assembly "Microsoft.Office.Interop.Outlook" | out-null
$olFolders = "Microsoft.Office.Interop.Outlook.OlDefaultFolders" -as [type]
$outlook = new-object -comobject outlook.application
$namespace = $outlook.GetNameSpace("MAPI")
$folder = $namespace.getDefaultFolder($olFolders::olFolderCalendar)

#Now you can search for Calendar Objects just like any other type
#In the example below, I'm searching for entries with a 
#subject of Monthly Budget Meeting that starts as of the 
#current date andd time

$folder.items |?{$_.Subject -like "*Monthly Budget Meeting*" -and $_.Start -gt (get-date)}|%{$_.delete()}

#End of script.  Now you know how to search and 
#delete multiple appointments

Sunday, February 10, 2013

PowerShell: Cleaning up Music File Names

I've been helping a friend manage his plethora of digital music.  Anyone who's acquired music has noticed the many ways filenames have been created.  Since Windows can display extra columns of information that coincide with MP3 tags, he decided the song names should be the filenames as the files would stay in the Artist/Album folders.

Here's a sample of the files original names:

After much research, I found the Title tag was usually a cleaner file name source than the actual file name.  I also noticed that hyphens were used a bunch and the section after the last hyphen was the song's name.  I used these two findings combined with character filters to come up with this:

PowerShell versions 1 and 2 balk at the [brackets] in a filename unless you perform some trickery.  PowerShell 3 has overcome this limitation -- but I'm using PS 2.0 for this script.  The script is not perfect but at least gets you in the general area.  The script does NOT -recurse (trickle down subfolders) since it's best to check your progress one folder at a time.

Here is the script if you'd like to give it a shot.  Place the .PS1 file with your other scripts and run it from the music folder to be affected.


$shell = new-object -com shell.application
$dirname = (get-item .\).fullname
$filename = (get-item .\*)|foreach-object{$_.name}

foreach($file in $filename){

#original filename holder

$fileholder = $file

#get the songs Title (item number 21 (if it exists)) property from the file

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

#if the title isn't empty, use it for the filename.
#Note: This is specifically for MP3's; you'd have to add other lines for 
#other music file extensions

if ($title -gt 0){$file = ($title + '.mp3')}

#clean extraneous characters from the filename
#experiment by adding filters which serve you best

$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 ('\)','')

#Split the filename at the hyphen and only keep the last portion
#since that's normally the song name. -1 means get the last one.

$file9 = $file8.split('-')[-1]

#rename the file after all the modifications

rename-item -path ($dirname + '\' + $fileholder) -newname $file9
}

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.

PowerShell: Passing PS Variables to Batch Files

I couldn't find many easy ways to transfer variables from PowerShell to cmd.exe batch files so I came up with my own solution.  We delete the old temp variable holding file, use PowerShell to create the variable and write the output to a go-between batch file, call that go-between batch file from your original batch file, and use the transferred variable.  Let me know if you don't get it, have questions, or have better suggestions:

1. Delete the variable-holding batch file from the last time it was used:
If exist d:\computername.bat del d:\computername.bat >nul

2.  From your batch file, create your PowerShell variable (I wanted to pick up the computer name):

powershell "$ComputerName = ('HQ-' + (gwmi win32_systemenclosure).SMBIOSAssetTag);write ('set PC=' + $computername)|out-file d:\computername.bat -encoding ASCII"

Note: In your new computername.bat file you have:
Set PC=HQ-R0xxxx
Which is a valid DOS batch command to create a variable named PC.

3. By writing the results into a batch file (computername.bat), you can call the new batch file from your original one.  Also, by writing a batch command to set a DOS variable, you've now transferred your PowerShell variable to a batch file.  From your original script:
call d:\computername.bat

4.  Now you can use the %PC% variable in your DOS batch file without having to load PowerShell each time you want to pull up the variable.  Obviously you can create all your variables from one PowerShell instance and have the command write out all the Set commands.

Also note, most systems have a restrictive PowerShell script execution policy so writing PS one-liners makes them easier to run since you don't have to worry about the script policy.

Example Batch File:


@Echo Off
if exist d:\computername.bat del d:\computername.bat >nul
PowerShell "$ComputerName = ('HQ-' + (gwmi win32_systemenclosure).SMBIOSAssetTag);write ('set PC=' + $computername)|out-file d:\computername.bat -encoding ASCII"
call d:\computername.bat
:InstallImage
cls
Echo.
Echo                               MAIN IMAGING MENU (%PC%)
Echo.
...


Thursday, January 31, 2013

PowerShell: Removing First 3 Characters from Filenames of Parent and Subfolders


I found several examples of renaming files but this one is simple and easy to change.

gci -include *.txt -recurse|ren -newname {($_.name).substring(3)}

Note: no carriage return, this is a single command
Note: Doesn't like spaces in the filenames

Run this command from the parent folder and it'll rename all the file types in the folder and all subfolders.  The only limitation I found is special characters in the folder or filename.

Wednesday, February 15, 2012

Windows 7 Run Commands

I recently joined a Microsoft System Administrators group in Linkedin and found this list of commands available to anyone running Windows 7.  I find running commands to access programs, control panel applets, and the like is quicker by pressing (Windows Key) + R and typing in a command.  Here is the list of commands:


Administrative Tools

Administrative Tools = control admintools
Authorization Manager = azman.msc
Component Services = dcomcnfg
Certificate Manager = certmgr.msc
Direct X Troubleshooter = dxdiag
Display Languages = lpksetup
ODBC Data Source Administrator = odbcad32
File Signature Verification Tool = sigverif
Group Policy Editor = gpedit.msc
Add Hardware Wizard = hdwwiz.cpl
iSCSI Initiator = iscsicpl
Iexpress Wizard = iexpress
Local Security Settings = secpol.msc
Microsoft Support Diagnostic Tool = msdt
Microsoft Management Console = mmc
Print management = printmanagement.msc
Printer User Interface = printui
Problems Steps Recorder = psr
People Near Me = p2phost
Registry Editor = regedit or regedt32
Resoure Monitor = resmon
System Configuration Utility = msconfig
Resultant Set of Policy = rsop.msc
SQL Server Client Configuration = cliconfg
Task Manager = taskmgr
Trusted Platform Module = tpm.msc
TPM Security Hardware = TpmInit
Windows Remote Assistance = msra
Windows Share Folder Creation Wizard = shrpubw
Windows Standalong Update Manager = wusa
Windows System Security Tool = syskey
Windows Script Host Settings = wscript
Windows Version = winver
Windows Firewall with Advanced Security = wf.msc
Windows Memory Diagnostic = MdSched
Windows Malicious Removal Tool = mrt


Computer Management

Computer Management = compmgmt.msc or CompMgmtLauncher
Task Scheduler = control schedtasks
Event Viewer = eventvwr.msc
Shared Folders/MMC = fsmgmt.msc
Local Users and Groups = lusrmgr.msc
Performance Monitor = perfmon.msc
Device Manager = devmgmt.msc
Disk Management = diskmgmt.msc
Services = services.msc
Windows Management Infrastructure = wmimgmt.msc

Conrtol Panel

Control Panel = control
Action Center= wscui.cpl
Autoplay = control.exe /name Microsoft.autoplay
Backup and Restore = sdclt
Create a System Repair disc = recdisc
BDE Administrator = bdeadmin.cpl
Color Management = colorcpl
Credential Manager = control.exe /name Microsoft.CredentialManager
Credential Manager Stored User Names and Passwords = credwiz
Date and Time Properties = timedate.cpl
Default Programs = control.exe /name Microsoft.DefaultPrograms
Set Program Access and Computer Defaults = control appwiz.cpl,,3 or ComputerDefaults
Devices and Printers = control printers
Devices and Printers Add a Device = DevicePairingWizard
Display = dpiscaling
Screen Resolution = desk.cpl
Display Color Calibration = dccw
Cleartype Text Tuner = cttune
Folders Options = control folders
Fonts = control fonts
Getting Started = GettingStarted
HomeGroup = control.exe /name Microsoft.HomeGroup
Indexing Options = control.exe /name Microsoft.IndexingOptions
Internet Properties = inetcpl.cpl
Keyboard = control keyboard
Location and Other Sensors = control.exe /name Microsoft.LocationandOtherSensors
Location Notifications = LocationNotifications
Mouse = control mouse or main.cpl
Network and Sharing Center = control.exe /name Microsoft.NetworkandSharingCenter
Network Connections = control netconnections or ncpa.cpl
Notification Area Icons = control.exe /name Microsoft.NotificationAreaIcons
Parental Controls = control.exe /name Microsoft.ParentalControls
Performance Information = control.exe /name Microsoft.PerformanceInformationandTools
Personalization = control desktop
Windows Color and Appearance = control color
Phone and Modem Options = telephon.cpl
Power Configuration = powercfg.cpl
Programs and Features = appwiz.cpl or control appwiz.cpl
Optional Features Manager = optionalfeatures or control appwiz.cpl,,2
Recovery = control.exe /name Microsoft.Recovery
Regional and Language = intl.cpl
RemoteApp = control.exe /name Microsoft.RemoteAppandDesktopConnections
Sound = mmsys.cpl
Volume Mixer = sndvol
System Properties = sysdm.cpl or Windows logo key + Pause/Break
SP ComputerName Tab = SystemPropertiesComputerName
SP Hardware Tab = SystemPropertiesHardware
SP Advanced Tab = SystemPropertiesAdvanced
SP Performance = SystemPropertiesPerformance
SP Data Execution Prevention = SystemPropertiesDataExecutionPrevention
SP Protection Tab = SystemPropertiesProtection
SP Remote Tab = SystemPropertiesRemote
Windows Activation = slui
Windows Activation Phone Numbers = slui 4
Taskbar and Start Menu = control.exe /name Microsoft.TaskbarandStartMenu
Troubleshooting = control.exe /name Microsoft.Troubleshooting
User Accounts = control.exe /name Microsoft.UserAccounts
User Account Control Settings = UserAccountControlSettings
User Accounts Windows 2000/domain version = netplwiz or control userpasswords2
Encryption File System = rekeywiz
Windows Anytime Upgrade = WindowsAnytimeUpgradeui
Windows Anytime Upgrade Results = WindowsAnytimeUpgradeResults
Windows CardSpace = control.exe /name Microsoft.cardspace
Windows Firewall = firewall.cpl
WindowsSideshow = control.exe /name Microsoft.WindowsSideshow
Windows Update App Manager = wuapp

Accessories

Calculator = calc
Command Prompt = cmd
Connect to a Network Projector = NetProj
Presentation Settings = PresentationSettings
Connect to a Projector = displayswitch or Windows logo key + P
Notepad = notepad
Microsoft Paint = mspaint.exe
Remote Desktop Connection = mstsc
Run = Windows logo key + R
Snipping Tool = snippingtool
Sound Recorder = soundrecorder
Sticky Note = StikyNot
Sync Center = mobsync
Windows Mobility Center (Only on Laptops) = mblctr or Windows logo key + X
Windows Explorer = explorer or Windows logo key + E
Wordpad = write
Ease of Access Center = utilman or Windows logo key + U
Magnifier = magnify
Narrator = Narrator
On Screen Keyboard = osk
Private Character Editor = eudcedit
Character Map = charmap
Ditilizer Calibration Tool = tabcal
Disk Cleanup Utility = cleanmgr
Defragment User Interface = dfrgui
Internet Explorer = iexplore
Rating System = ticrf
Internet Explorer (No Add-ons) = iexplore -extoff
Internet Explorer (No Home) = iexplore about:blank
Phone Dialer = dialer
Printer Migration = PrintBrmUi
System Information = msinfo32
System Restore = rstrui
Windows Easy Transfer = migwiz
Windows Media Player = wmplayer
Windows Media Player DVD Player = dvdplay
Windows Fax and Scan Cover Page Editor = fxscover
Windows Fax and Scan = wfs
Windows Image Acquisition = wiaacmgr
Windows PowerShell ISE = powershell_ise
Windows PowerShell = powershell
XPS Viewer = xpsrchvw

Open Documents folder = documents
Open Pictures folder = pictures
Open Music folder = music
Open Favorites folder = favorites
Open Downloads folder = downloads
Logs out of Windows = logoff
Shuts Down Windows = shutdown


Reference