27 November 2013

Disable Windows Media Center

If you are needing to disable Windows Media Center in Windows 7 by command line, here is a script that will do just that. This script will not only disable it, but it will also add an add/remove programs and HKCR entry so that both WMI and SCCM can detect the service was disabled.

You can download the script from here.

 #*******************************************************************************  
 #   Author: Mick Pletcher  
 #    Date: 16 August 2013  
 #  
 #   Program: Windows Media Center  
 #*******************************************************************************  
 cls  

 #Declare Global Memory  
 Set-Variable -Name a -Scope Global -Force  
 Set-Variable -Name Output -Scope Global -Force  

 Function AddRemovePrograms($KeyName, $DisplayName, $Version){  

      #Define Local Memory  
      New-PSDrive -Name HKCR -PSProvider Registry -Root HKEY_CLASSES_ROOT  
      Set-Variable -Name AddRemKey -Scope Local -Force  
      Set-Variable -Name guid -Scope Local -Force  
      Set-Variable -Name ProductsKey -Scope Local -Force  

      If (!(Test-Path c:\windows\GSPBox_Icon.bmp)){  
           Copy-Item -Path \\global.gsp\data\clients\na_clients\Build\Add-ins\GSPBox_Icon.bmp -Destination c:\Windows -Force  
      }  
      $AddRemKey = "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"  
      $ProductsKey = "HKCR:\Installer\Products\"  
      New-Item -Path $AddRemKey -Name $KeyName –Force  
      New-ItemProperty -Path $AddRemKey"\"$KeyName -Name DisplayName -Value $DisplayName -PropertyType String  
      New-ItemProperty -Path $AddRemKey"\"$KeyName -Name DisplayVersion -Value $Version -PropertyType String  
      New-ItemProperty -Path $AddRemKey"\"$KeyName -Name UninstallString -Value " " -PropertyType String  
      New-ItemProperty -Path $AddRemKey"\"$KeyName -Name Publisher -Value "Gresham, Smith and Partners" -PropertyType String  
      New-ItemProperty -Path $AddRemKey"\"$KeyName -Name DisplayIcon -Value "c:\windows\GSPBox_Icon.bmp" -PropertyType String  
      $guid = [guid]::NewGuid().ToString("N")  
      $guid.ToString()  
      $guid = $guid.ToUpper()  
      New-Item -Path $ProductsKey -Name $guid –Force  
      New-ItemProperty -Path $ProductsKey"\"$guid -Name ProductName -Value $DisplayName -PropertyType String -Force  

      #Cleanup Local Memory  
      remove-psdrive -name HKCR  
      Remove-Variable -Name AddRemKey -Scope Local -Force  
      Remove-Variable -Name guid -Scope Local -Force  
      Remove-Variable -Name ProductsKey -Scope Local -Force  

 }  

 Invoke-Command {dism.exe /online /disable-feature /featurename:MediaCenter /norestart}  
 $a = Invoke-Command {dism.exe /online /get-featureinfo /featurename:MediaCenter}  
 $Output = $a | Select-String "State : Disabled"  
 Write-Host $Output  
 If ($Output -like "State : Disabled"){  
      AddRemovePrograms "MediaCenter" "MediaCenter" "Disabled"  
 }  

 #Cleanup Global Memory  
 Remove-Variable -Name a -Scope Global -Force  
 Remove-Variable -Name Output -Scope Global -Force  

26 November 2013

Add/Remove Program entries

Sometimes it is necessary to add an add/remove programs entry. There are instances where an application is independent and requires not installation and you want to make sure it is copied to the system, or you use add/remove programs to verify a service is enabled/disabled. For whatever reason you need to add an entry you want to also add the registry keys so that a WMI query will also detect the entry. The script below will do just that. It creates a GUID, which is required to write the entry in the HKCR key. This is where the WMI will read from, not from the Uninstall directory.

You can download the script from here.

 Function AddRemovePrograms($KeyName, $DisplayName, $Version){  

      #Define Local Memory  
      New-PSDrive -Name HKCR -PSProvider Registry -Root HKEY_CLASSES_ROOT  
      Set-Variable -Name AddRemKey -Scope Local -Force  
      Set-Variable -Name guid -Scope Local -Force  
      Set-Variable -Name ProductsKey -Scope Local -Force 
 
      If (!(Test-Path c:\windows\GSPBox_Icon.bmp)){  
           Copy-Item -Path \\global.gsp\data\clients\na_clients\Build\Add-ins\GSPBox_Icon.bmp -Destination c:\Windows -Force  
      }  
      $AddRemKey = "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"  
      $ProductsKey = "HKCR:\Installer\Products\"  
      New-Item -Path $AddRemKey -Name $KeyName –Force  
      New-ItemProperty -Path $AddRemKey"\"$KeyName -Name DisplayName -Value $DisplayName -PropertyType String  
      New-ItemProperty -Path $AddRemKey"\"$KeyName -Name DisplayVersion -Value $Version -PropertyType String  
      New-ItemProperty -Path $AddRemKey"\"$KeyName -Name UninstallString -Value " " -PropertyType String  
      New-ItemProperty -Path $AddRemKey"\"$KeyName -Name Publisher -Value "Gresham, Smith and Partners" -PropertyType String  
      New-ItemProperty -Path $AddRemKey"\"$KeyName -Name DisplayIcon -Value "c:\windows\GSPBox_Icon.bmp" -PropertyType String  
      $guid = [guid]::NewGuid().ToString("N")  
      $guid.ToString()  
      $guid = $guid.ToUpper()  
      New-Item -Path $ProductsKey -Name $guid –Force  
      New-ItemProperty -Path $ProductsKey"\"$guid -Name ProductName -Value $DisplayName -PropertyType String -Force  

      #Cleanup Local Memory  
      remove-psdrive -name HKCR  
      Remove-Variable -Name AddRemKey -Scope Local -Force  
      Remove-Variable -Name guid -Scope Local -Force  
      Remove-Variable -Name ProductsKey -Scope Local -Force  
 }  

25 November 2013

Verify applications were installed during build process

As many of you have probably experienced, SCCM and MDT do not always install all of the applications that are in the task sequence list, even if it returned an error code 0. This can be rather annoying, especially when it happens in the build process of the golden image. In order to get around this issue, I wrote the PowerShell script below that will use WMI to verify all of the applications were installed during the task sequence process. All that you should have to do to make custom changes for your environment is to open up the script and add your apps. You will see four examples I put in this script, AppInstalled "Adobe Reader"  being one example. The Adobe Reader in parenthesis can be changed to any app, such as Microsoft Office. You do not need to enter the entire application name, as I have written the function to be able to search for just part of the name. I used the Adobe Reader example because your company may have more than one version of reader and this can search any version being just a portion of the name.

In order to properly implement this, I would suggest putting this as a task sequence and then immediately pausing the build so that you can review the output of this and manually install any applications that may have failed before the golden image is generated. To pause the build for MDT, you can initiate the LTISuspend.wsf as a task sequence. SCCM does not have this wsf file, so you can create a simple, one line VBS file that calls the MSGBOX which will wait for you to click OK on. The VBS can also be used in MDT instead of the LTISuspend.wsf.

You can download this script here.

 #*******************************************************************************  
 #   Author: Mick Pletcher  
 #    Date: 25 November 2013  
 #  
 #   Program: Check Build  
 #*******************************************************************************  
 Clear-Host  

 #Declare Global Memory  
 $app = ,@()  
 Set-Variable -Name Count -Scope Global -Value 1 -Force  
 Set-Variable -Name OS -Scope Global -Force  
 Set-Variable -Name RelativePath -Scope Global -Force  

 Function RenameWindow ($Title) {  

      #Declare Local Memory  
      Set-Variable -Name a -Scope Local -Force
  
      $a = (Get-Host).UI.RawUI  
      $a.WindowTitle = $Title  

      #Cleanup Local Memory  
      Remove-Variable -Name a -Scope Local -Force
  
 }  

 Function AppInstalled($Description) {
  
      #Declare Local Memory  
      Set-Variable -Name AppName -Scope Local -Force  
      Set-Variable -Name AppLocal -Scope Local -Force  
      Set-Variable -Name Desc -Scope Local -Force  
      Set-Variable -Name Output -Scope Local -Force
  
      $object = New-Object -TypeName PSObject  
      #Change '%application%' to whatever app you are calling  
      $Desc = [char]34+"description like"+[char]32+[char]39+[char]37+$Description+[char]37+[char]39+[char]34  
      $Output = wmic product where $Desc get Description  
      $Output | ForEach-Object {  
           $_ = $_.Trim()  
             if(($_ -ne "Description")-and($_ -ne "")){  
                $AppName = $_  
             }  
      }  
      $AppLocal = New-Object System.Object  
      $AppLocal | Add-Member -type NoteProperty -name Application -value $Description  
      If ($AppName -ne $null) {  
           #$Global:app+=,@($Description,"Installed")  
           $AppLocal | Add-Member -type NoteProperty -name Status -value "Installed"  
      } else {  
           #$Global:app+=,@($Description,"Not Installed")  
           $AppLocal | Add-Member -type NoteProperty -name Status -value "Not Installed"  
      }  
      $Global:app += $AppLocal  
      $AppLocal | Select Application  
      $Global:Count++  

      #Cleanup Local Memory  
      Remove-Variable -Name AppName -Scope Local -Force  
      Remove-Variable -Name AppLocal -Scope Local -Force  
      Remove-Variable -Name Desc -Scope Local -Force  
      Remove-Variable -Name Output -Scope Local -Force
  
 }  

 cls  
 Write-Host "Processing Applications"  
 Write-Host  
 RenameWindow "Check Build Installs"  
 AppInstalled "Dell Client System Update"  
 AppInstalled "Adobe Reader"  
 AppInstalled "Microsoft Lync"  
 cls  
 Write-Host "Installation Report"  
 Write-Host  
 $app | Format-Table
  
 #Cleanup Global Memory  
 $app.Clear()  
 Remove-Variable -Name Count -Scope Global -Force  
 Remove-Variable -Name OS -Scope Global -Force  
 Remove-Variable -Name RelativePath -Scope Global -Force  

Dell Client System Update for the SCCM & MDT Build

The DCSU is a great utility that Dell has made available to update the drivers and driver applications on Dell systems. The industry I work in requires specific drivers for specific applications, which makes the DCSU not a great utility for us after the system is built. However, the utility is great for making sure all of the drivers are installed during the build process. I have written the script below that will install the DCSU, run it with a specific policy XML file you create, and then comes back and uninstalls it.

You can download the script from here.

NOTE: If you are having Bitlocker enabled during your build, make sure this is executed before bitlocker is enabled, or add a function that will pause Bitlocker.


 #*******************************************************************************  
 #   Author: Mick Pletcher  
 #    Date: 25 November 2013  
 #  
 #   Program: Dell Client System Update  
 #*******************************************************************************  
 Clear-Host  
 #Declare Global Memory  
 Set-Variable -Name OS -Scope Global -Force  
 Set-Variable -Name RelativePath -Scope Global -Force  
 Function RenameWindow ($Title) {  
      #Declare Local Memory  
      Set-Variable -Name a -Scope Local -Force  
      $a = (Get-Host).UI.RawUI  
      $a.WindowTitle = $Title  
      #Cleanup Local Memory  
      Remove-Variable -Name a -Scope Local -Force  
 }  
 Function GetRelativePath {  
      $Global:RelativePath=(split-path $SCRIPT:MyInvocation.MyCommand.Path -parent)+"\"  
 }  
 Function GetOSArchitecture {  
      $Global:Architecture = Get-WMIObject win32_operatingsystem  
      $Global:Architecture = $Global:Architecture.OSArchitecture  
      #Answers: 32-bit, 64-bit  
 }  
 Function ProcessRunning($Description,$Process) {  
      #Declare Local Memory  
      Set-Variable -Name ProcessActive -Scope Local -Force  
      Write-Host $Description"....." -NoNewline  
      $ProcessActive = Get-Process $Process -ErrorAction SilentlyContinue  
      if($ProcessActive -eq $null) {  
           Write-Host "Not Running" -ForegroundColor Yellow  
      } else {  
           Write-Host "Running" -ForegroundColor Red  
      }  
      #Cleanup Local Memory  
      Remove-Variable -Name ProcessActive -Scope Local -Force  
 }  
 Function KillProcess($Description,$Process) {  
      #Declare Local Memory  
      Set-Variable -Name ProcessActive -Scope Local -Force  
      Write-Host $Description"....." -NoNewline  
      $ProcessActive = Stop-Process -Name $Process -Force  
      If ($ProcessActive -eq $null) {  
           Write-Host "Killed" -ForegroundColor Yellow  
      } else {  
           Write-Host "Still Running" -ForegroundColor Red  
      }  
 }  
 Function CopyFile($FileName,$SourceDir,$DestinationDir,$NewFileName) {  
      If ($SourceDir.SubString($SourceDir.length-1) -ne "\") {  
           $SourceDir = $SourceDir+"\"  
      }  
      If ((Test-Path -Path $SourceDir$FileName) -eq $true) {  
           Write-Host "Copying"$FileName"....."  
           Copy-Item -Path $SourceDir$FileName -Destination $DestinationDir -Force  
           If ($NewFileName -ne "") {  
                If ($DestinationDir.SubString($DestinationDir.length-1) -ne "\") {  
                     $DestinationDir = $DestinationDir+"\"  
                }  
                Rename-Item -Path $DestinationDir$FileName -NewName $NewFileName -Force  
           }  
      }  
 }  
 Function BalloonTip($ApplicationName, $Status, $DisplayTime) {  
      #Declare Local Memory  
      Set-Variable -Name balloon -Scope Local -Force  
      Set-Variable -Name icon -Scope Local -Force  
      Set-Variable -Name path -Scope Local -Force  
      [system.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms') | Out-Null  
      $balloon = New-Object System.Windows.Forms.NotifyIcon  
      $path = Get-Process -id $pid | Select-Object -ExpandProperty Path  
      $icon = [System.Drawing.Icon]::ExtractAssociatedIcon($path)  
      $balloon.Icon = $icon  
      $balloon.BalloonTipIcon = 'Info'  
      $balloon.BalloonTipTitle = "Gresham, Smith and Partners"  
      $balloon.BalloonTipText = $ApplicationName+[char]13+[char]13+$Status  
      $balloon.Visible = $true  
      $balloon.ShowBalloonTip($DisplayTime)  
      #Cleanup Local Memory  
      Remove-Variable -Name balloon -Scope Local -Force  
      Remove-Variable -Name icon -Scope Local -Force  
      Remove-Variable -Name path -Scope Local -Force  
 }  
 Function UninstallOldMSIApplication($Description) {  
      #Declare Local Memory  
      Set-Variable -Name AppName -Scope Local -Force  
      Set-Variable -Name Arguments -Scope Local -Force  
      Set-Variable -Name Desc -Scope Local -Force  
      Set-Variable -Name ErrCode -Scope Local -Force  
      Set-Variable -Name GUID -Scope Local -Force  
      Set-Variable -Name Output -Scope Local -Force  
      Set-Variable -Name Output1 -Scope Local -Force  
      #Change '%application%' to whatever app you are calling  
      $Desc = [char]34+"description like"+[char]32+[char]39+[char]37+$Description+[char]37+[char]39+[char]34  
      $Output1 = wmic product where $Desc get Description  
      cls  
      $Output1 | ForEach-Object {  
           $_ = $_.Trim()  
        if(($_ -ne "Description")-and($_ -ne "")){  
          $AppName = $_  
        }  
      }  
      If ($AppName -eq $null) {  
           return  
      }  
      Write-Host "Uninstalling"$AppName"....." -NoNewline  
      $Output = wmic product where $Desc get IdentifyingNumber  
      $Output | ForEach-Object {  
           $_ = $_.Trim()  
             if(($_ -ne "IdentifyingNumber")-and($_ -ne "")){  
               $GUID = $_  
             }  
      }  
      $Arguments = "/X"+[char]32+$GUID+[char]32+"/qb- /norestart"  
      $ErrCode = (Start-Process -FilePath "msiexec.exe" -ArgumentList $Arguments -Wait -Passthru).ExitCode  
      $Result = (AppInstalled $Description)  
      If ($Result) {  
           Write-Host "Failed with error code"$ErrCode -ForegroundColor Red  
      } else {  
           Write-Host "Uninstalled" -ForegroundColor Yellow  
      }  
      #Cleanup Local Memory  
      Remove-Variable -Name AppName -Scope Local -Force  
      Remove-Variable -Name Arguments -Scope Local -Force  
      Remove-Variable -Name Desc -Scope Local -Force  
      Remove-Variable -Name ErrCode -Scope Local -Force  
      Remove-Variable -Name GUID -Scope Local -Force  
      Remove-Variable -Name Output -Scope Local -Force  
      Remove-Variable -Name Output1 -Scope Local -Force  
 }  
 Function InstallMSIApplication($App,$Switches,$Transforms,$Desc) {  
      #Declare Local Memory  
      Set-Variable -Name App -Scope Local -Force  
      Set-Variable -Name Arguments -Scope Local -Force  
      Set-Variable -Name ErrCode -Scope Local -Force  
      Set-Variable -Name Result -Scope Local -Force  
      Write-Host "Installing"$Desc"....." -NoNewline  
      $App = [char]32+[char]34+$RelativePath+$App+[char]34  
      $Switches = [char]32+$Switches  
      If ($Transforms -ne $null) {  
           $Transforms = [char]32+"TRANSFORMS="+$RelativePath+$Transforms  
           $Arguments = "/I"+$App+$Transforms+$Switches  
      } else {  
           $Arguments = "/I"+$App+$Switches  
      }  
      $ErrCode = (Start-Process -FilePath "msiexec.exe" -ArgumentList $Arguments -Wait -Passthru).ExitCode  
      $Result = (AppInstalled $Desc)  
      If ($Result) {  
           Write-Host "Installed" -ForegroundColor Yellow  
      } else {  
           Write-Host "Failed with error"$ErrCode -ForegroundColor Red  
      }  
      #Cleanup Local Memory  
      Remove-Variable -Name App -Scope Local -Force  
      Remove-Variable -Name Arguments -Scope Local -Force  
      Remove-Variable -Name ErrCode -Scope Local -Force  
      Remove-Variable -Name Result -Scope Local -Force  
 }  
 Function InstallEXEApplication($App,$Switches,$Desc) {  
      #Declare Local Memory  
      Set-Variable -Name ErrCode -Scope Local -Force  
      Set-Variable -Name Result -Scope Local -Force  
      Write-Host "Installing <Application>....." -NoNewline  
      $App = [char]32+[char]34+$RelativePath+$App+[char]34  
      $ErrCode = (Start-Process -FilePath $App -ArgumentList $Switches -Wait -Passthru).ExitCode  
      $Result = (AppInstalled $Desc)  
      If ($Result) {  
           Write-Host "Installed" -ForegroundColor Yellow  
      } else {  
           Write-Host "Failed with error"$ErrCode -ForegroundColor Red  
      }  
      #Cleanup Local Memory  
      Remove-Variable -Name ErrCode -Scope Local -Force  
      Remove-Variable -Name Result -Scope Local -Force  
 }  
 Function AppInstalled($Description) {  
      #Declare Local Memory  
      Set-Variable -Name AppName -Scope Local -Force  
      Set-Variable -Name Output -Scope Local -Force  
      #Change '%application%' to whatever app you are calling  
      $Description = [char]34+"description like"+[char]32+[char]39+[char]37+$Description+[char]37+[char]39+[char]34  
      $Output = wmic product where $Description get Description  
      $Output | ForEach-Object {  
           $_ = $_.Trim()  
             if(($_ -ne "Description")-and($_ -ne "")){  
                $AppName = $_  
             }  
      }  
      If ($AppName -eq $null) {  
           return $false  
      } else {  
           return $true  
      }  
      #Cleanup Local Memory  
      Remove-Variable -Name AppName -Scope Local -Force  
      Remove-Variable -Name Output -Scope Local -Force  
 }  
 Function ExecuteDCSU($App,$Switches) {  
      #Declare Local Memory  
      Set-Variable -Name ErrCode -Scope Local -Force  
      $App = [char]34+"C:\Program Files (x86)\Dell\ClientSystemUpdate\"+$App+[char]34  
      $Switches = "/policy"+[char]32+$RelativePath+$Switches  
      $ErrCode = (Start-Process -FilePath $App -ArgumentList $Switches -Wait -Passthru).ExitCode  
      If ($ErrCode -eq 0) {  
           Write-Host "Drivers Updated" -ForegroundColor Yellow  
      } else {  
           Write-Host "Failed with error"$ErrCode -ForegroundColor Red  
      }  
      #Cleanup Local Memory  
      Remove-Variable -Name ErrCode -Scope Local -Force  
 }  
 RenameWindow "Install Dell Client System Update"  
 GetRelativePath  
 GetOSArchitecture  
 BalloonTip "Dell Client System Update" "Updating Drivers...." 10000  
 InstallMSIApplication "Dell Client System Update.msi" "/qb- /norestart" $null "Dell Client System Update"  
 ExecuteDCSU "dcsu-cli.exe" "BuildPolicy.xml"  
 UninstallOldMSIApplication "Dell Client System Update"  
 BalloonTip "Dell Client System Update" "Driver Update Complete" 30000  
 #Cleanup Global Memory  
 Remove-Variable -Name OS -Scope Global -Force  
 Remove-Variable -Name RelativePath -Scope Global -Force  

31 October 2013

Microsoft Lync 2013: Error 1406 Could not write value to key

This error is caused by registry key permissions. The first thing I did was to go in and change the permissioning to everyone on the key(s) it was not able to write to. This did no good. To get right to the solution after much more troubleshooting, I ended up deleting the Key and subkeys under the CLSID. This was the only way I was able to resolve the issue. I am not saying to delete every key under CLSID, but only the one specified in the error message and its subkeys. This resolved the issue and caused no other issues with the rest of the office suite. I would recommend backing up the key before doing this.

25 October 2013

Securely Removing Personal Data from your Corporate Windows Computer

You have been using your company computer for your own private use, especially if it is a laptop. Now you want to securely remove the personal data off of the company equipment. First place, it's not wise to store your personal data on a company computer. People can and do look at it, especially if there are issues with your equipment. There may be laws that cover those files/emails as private property, but that's not going to stop everyone from snooping and possibly gossiping. There are ways of opening up files and looking at the contents without the system logging it.

WARNING: Do not remove data that pertains to the company. It can get you into big trouble. You could possibly lose your job. It could even go as far as civil and/or criminal court. Only remove data that is strictly personal.

Here is a list of the things you will want to clean off of the system:

  • E-mail
  • Applications
  • Files
  • Pictures
  • Music
  • Videos
  • Browser
    • Bookmarks
    • History
    • Cache
    • Cookies
    • Passwords
  • System Restore Points

Limitations

  • If your company backs up the data on your system, it's not going to do a lot of good to securely delete everything because they will have a backup of it.
  • Most companies retain data for a period of time on the exchange servers. They will be able to recover the emails from the server if the retention period is still active.


Here is the process you will want to follow in this order to securely delete all of your personal data:

  1. Export all of your personal emails to a pst file if it's Outlook, or a csv/txt/xml file for any other email type. You may also want to check inside your company email inbox for personal emails and export them out, or forward and delete them. 
  2. Delete any personal email accounts that might be associated with Outlook.
  3. If you were using Outlook, the emails will also be stored in an OST file that you might want to think about deleting. It will be recreated the next time you open Outlook, but this time it will not contain the emails from the personal accounts you deleted. The OST file is used to cache down the emails for quick access.
  4. Export your personal browser bookmarks to a text file.
  5. Export your browser cookies if you prefer. 
  6. You can't transfer applications to a new system, so you will want to get your application licensing information, such as product keys, and then uninstall the applications.
  7. Transfer the files/music/videos/cookies/pictures/exported emails/bookmarks either to a USB thumb drive or to the cloud.
  8. Uninstall any cloud drive applications that link your system to your cloud storage.
  9. Next, you will want to delete the personal files. While deleting files, include the %TEMP% directory. This contains temporary files that should not hurt anything on the computer if they are deleted, but there may also be personal files stored there. 
  10. Use CCleaner to clean up your system of all cookies, temporary internet files, browser history, index.dat files, recycle bin, temporary files, and more.
  11. Delete all System Restore Points. The restore points can be used to restore data that you had deleted off of the system.
  12. Create a new system restore point. This will be created without the data of all the files you have deleted.
  13. Use CCleaner to clean up the registry. It is recommended to use the registry backup feature before deleting any keys. 
  14. Use CCleaner Drive Wiper (Free Space Only) to wipe all free space sectors. It is recommended to overwrite with 3 passes. This will stop anyone from being able to recover a system restore point or files. This process will take a long time, so it's recommended to do it at the end of the day. You can learn more on data deletion here.
  15. Create a new system restore point.
That should cover everything for most users on securely removing your personal data from a company computer. 

20 September 2013

SCCM: Package not updating on the distribution points

You have made changes to your installation package and it does not update on the distribution points, even after validating and redistributing. I ran into this issue and could not figure out why it was doing this. I ended up having to create a new package until I came across the answer in the deployment types tab. The way to make your package update appropriately is to click on the deployment types tab, select the package, and then click Update Content at the top. It's as simple as that. Thanks to Daniel Classon's blog on the differences between updating and refreshing a package, I was able to figure this out.  

23 August 2013

Find out who is logged on and logged off

Being an SCCM administrator, I often have to log into machines to see if a deployment went ok. Trying to login to machines and getting the message that someone is already logged in gets tiring. Ed Wilson originally wrote a script to tell you whether a user was logged onto a machine or not. I took his script, compacted it and made it more presentable. This script will read from a text file named Computers.txt located in the same directory as the script. PsLoggedon.exe also needs to be present in the same directory. This can be found in the package called PSTools. It has come to be a great asset to my work.

You can download this script from here.


 #*******************************************************************************  
 #   Author: Mick Pletcher  
 #    Date: 23 August 2013  
 #  
 #   Program: Who's Logged On and Logged Off?  
 #*******************************************************************************  

 #Declare Global Variables  
 Set-Variable -Name Command -Scope Global -Force  
 Set-Variable -Name Computer -Scope Global -Force  
 Set-Variable -Name Computers -Scope Global -Force  
 Set-Variable -Name i -Scope Global -Value 1 -Force  
 Set-Variable -Name Output -Scope Global -Force  
 Set-Variable -Name RelativePath -Scope Global -Force  
 Set-Variable -Name Results -Scope Global -Force  
 Set-Variable -Name Username -Scope Global -Force  

 Function RenameWindow ($Title) {  
      #Declare Local Memory  
      Set-Variable -Name a -Scope Local -Force  
      $a = (Get-Host).UI.RawUI  
      $a.WindowTitle = $Title  
      #Cleanup Local Memory  
      Remove-Variable -Name a -Scope Local -Force  
 }  

 Function GetRelativePath{  
      $Global:RelativePath=(split-path $SCRIPT:MyInvocation.MyCommand.Path -parent)+"\"  
 }  

 cls  
 RenameWindow "Who's Logged On and Logged Off?"  
 GetRelativePath  
 $Results = @()  
 $Username = @()  
 $Computers = Get-Content -Path $Global:RelativePath"Computers.txt"  
 $Size = $Computers.Length  
 Foreach ($Computer in $Computers) {  
      Write-Host "Scanning System "$i" of "$Size  
      Write-Host  
      Write-Host "System:"$Computer  
      $Command = $Global:RelativePath+"PsLoggedon.exe -x -l \\$Computer"  
      $Output = Invoke-Expression $Command  
      If ($Output.SyncRoot[2] -eq "Users logged on locally:") {  
           $Username += $Output.SyncRoot[3].Trim()  
      } else {  
           $Username += "N/A"  
      }  
      $Output = $Output.SyncRoot[2]  
      $Output = $Output.Substring(0,$Output.Length-1)  
      $Results += $Output  
      $i = $i + 1  
      cls  
 }  
 cls  
 for ($i=0 ; $i -lt $Results.length ; $i++) {  
       If ($Results[$i] -eq "No one is logged on locally") {  
           Write-Host $Computers[$i]": "$Results[$i] -BackgroundColor Yellow -ForegroundColor Black  
      } elseIf ($Results[$i] -eq "Users logged on locally") {  
           Write-Host $Computers[$i]": "$Results[$i]" -- "$Username[$i]-ForegroundColor White  
      } else {  
           Write-Host $Computers[$i]": "$Results[$i]" -- "$Username[$i]-ForegroundColor Red  
      }  
 }  

 #Cleanup Global Variables  
 Remove-Variable -Name Command -Scope Global -Force  
 Remove-Variable -Name Computer -Scope Global -Force  
 Remove-Variable -Name Computers -Scope Global -Force  
 Remove-Variable -Name i -Scope Global -Force  
 Remove-Variable -Name Output -Scope Global -Force  
 Remove-Variable -Name RelativePath -Scope Global -Force  
 Remove-Variable -Name Results -Scope Global -Force  
 Remove-Variable -Name Username -Scope Global -Force  

07 August 2013

Application Uninstall Script

This script will uninstall an application with just the partial description that is listed in Add/Remove programs. It searches the product list and then grabs the GUID to use in the MSI uninstallation. At current, it will only uninstall apps that use an MSI installer. I am going to be updating this script to be able to use executables also.

You can download the script from here.

 Function UninstallOldApplication($Description) {  
      #Declare Local Memory  
      Set-Variable -Name AppName -Scope Local -Force  
      Set-Variable -Name Arguments -Scope Local -Force  
      Set-Variable -Name Code -Scope Local -Force  
      Set-Variable -Name GUID -Scope Local -Force  
      Set-Variable -Name Output -Scope Local -Force  
      #Change '%application%' to whatever app you are calling  
      $Description = [char]34+"description like"+[char]32+[char]39+[char]37+$Description+[char]37+[char]39+[char]34  
      $Output = wmic product where $Description get IdentifyingNumber  
      $Output1 = wmic product where $Description get Description  
      $Output1 | ForEach-Object {  
           $_ = $_.Trim()  
        if(($_ -ne "Description")-and($_ -ne "")){  
          $AppName = $_  
        }  
      }  
      Write-Host "Uninstalling"$AppName"....." -NoNewline  
      $Output | ForEach-Object {  
           $_ = $_.Trim()  
        if(($_ -ne "IdentifyingNumber")-and($_ -ne "")){  
          $GUID = $_  
        }  
      }  
      $Arguments = "/X"+[char]32+$GUID+[char]32+"/qb- /norestart"  
      $Code = (Start-Process -FilePath "msiexec.exe" -ArgumentList $Arguments -Wait -Passthru).ExitCode  
      If ($Code -eq 0) {  
           Write-Host "Uninstalled" -ForegroundColor Yellow  
      } else {  
           Write-Host "Failed" -ForegroundColor Red  
      }  
      #Cleanup Local Memory  
      Remove-Variable -Name AppName -Scope Local -Force  
      Remove-Variable -Name Arguments -Scope Local -Force  
      Remove-Variable -Name Code -Scope Local -Force  
      Remove-Variable -Name GUID -Scope Local -Force  
      Remove-Variable -Name Output -Scope Local -Force  
      Remove-Variable -Name Output1 -Scope Local -Force  
 }  

19 July 2013

Powershell: Reset Network Adaptor with Connectivity Verification

Here is a script that will disable and then re-enable the network interface on your pc. It will also verify if the network connection is re-established by testing the connection to google.com.

You can download the script from here.

 cls  
 #Declare Global Variables  
 Set-Variable -Name Computer -Scope Global -Force  
 Set-Variable -Name Active -Scope Global -Force  
 Set-Variable -Name Network -Scope Global -Force  
 Set-Variable -Name Networks -Scope Global -Force  
 Set-Variable -Name Output -Scope Global -Force  
 Set-Variable -Name RetVal -Scope Global -Force  
 $Computer = gc env:computername  
 $Networks = Get-WmiObject Win32_NetworkAdapter -ComputerName $Computer  
 Foreach ($Network in $Networks) {  
      If ($Network.NetEnabled -eq $true) {  
           $Active = $Network  
           Write-Host "Network Adaptor"  
           Write-host "   "$Network.Description  
           Write-Host  
           $RetVal = $Network.Disable()  
           If ($RetVal.ReturnValue -eq 0) {  
                Write-Host "Network adaptor is disabled"  
           }  
           Start-Sleep -Seconds 5  
           $RetVal = $Network.Enable()  
           If ($RetVal.ReturnValue -eq 0) {  
                Write-Host "Network adaptor is re-enabled"  
           }  
           Start-Sleep -Seconds 30  
           $Output = Test-Connection google.com -Quiet  
           If ($Output -eq $true) {  
                Write-Host "Network adaptor Restored"  
           } else {  
                Write-Host "Network adaptor unavailable"  
           }  
      }  
 }  
 Remove-Variable -Name Active -Scope Global -Force  
 Remove-Variable -Name Computer -Scope Global -Force  
 Remove-Variable -Name Network -Scope Global -Force  
 Remove-Variable -Name Networks -Scope Global -Force  
 Remove-Variable -Name Output -Scope Global -Force  
 Remove-Variable -Name RetVal -Scope Global -Force  

18 July 2013

SCCM: Deploying Autodesk Revit 2013

In order to deploy the Revit 2013 through SCCM, you will need to have the detection method setup. I used the msi product codes listed below. This is the complete list of all the applications that Revit Building Premium installs in the exact order as listed below. I entered all of the msi product codes below just to make sure the package was completely installed before SCCM marked it as successful.

For the deployment script, I used the VBScript I wrote, listed below, to install the package. I had to write a VBScript to install Revit because setup.exe opens up another instance of itself and then closes the original instance. This causes SCCM and MDT to think that it has completed, when it has not. The script pauses for several seconds and then looks for the setup.exe again to get around this. The script will also run from any location, as I have it to use the relative path at when it was executed from.

You can download the script from here.

Autodesk® Design Review 2013
{153DB567-6FF3-49AD-AC4F-86F8A3CCFDFB}

Autodesk® Revit® 2013
{7346B4A0-1300-0510-0409-705C0D862004}

AutoCAD® 2013
{5783F2D7-B001-0000-0102-0060B0CE6BBA}

Autodesk® Navisworks® Simulate 2013
{F17E30E2-7ED4-0000-8A8E-CAB597E3F8ED}

Autodesk® 3ds Max® Design 2013
{7D65612F-53B4-0409-85AA-21DF5A8E9455}

Autodesk® Showcase® 2013
{A15BFC7D-6A90-47E6-8C6E-D51B2929D8C8}

AutoCAD® Architecture 2013
{5783F2D7-B004-0000-0102-0060B0CE6BBA}

Autodesk® SketchBook® Designer 2013
{3CB60177-D3D2-4E9C-BE4D-8372B34B4C7F}

Autodesk® Inventor® Fusion 2013
{FFF5619F-2013-0064-A85E-9994F70A9E5D}

Autodesk® SketchBook® Designer for AutoCAD® 2013
{7B42AD25-3D13-4422-A445-F5E18BD963FC}

Autodesk Material Library 2013 - Medium Image Library
{58760EEC-8B6A-43F4-81AA-696E381DFADD}

Autodesk® Backburner 2013
{3D347E6D-5A03-4342-B5BA-6A771885F379}

Autodesk Inventor Server Engine For 3ds Max Design 2013
{BC66B242-DF13-1664-851B-00123612ED98}

3dsMax Composite 2013
{2F808931-D235-4FC7-90CD-F8A890C97B2F}

Autodesk® Revit Interoperability for 3ds Max 2013
{06E18300-BB64-1664-8E6A-2593FC67BB74}

Autodesk® Civil View 2013
{FE6DCC8D-427F-405C-A779-C93B6D9F77A5}

Autodesk® Essential Skills Movies for 3dsMax Design 2013
{62CBE596-1BB8-4D7B-A056-103287BAD1C4}

Autodesk Cloud sync
{EE5F74BC-5CD5-4EF2-86BA-81E6CF46A18F}


 '*******************************************************************************  
 '   Author: Mick Pletcher  
 '    Date: 20 November 2012  
 '  Modified:  
 '  
 ' Description: This will install Revit 2013  
 '*******************************************************************************  
 Option Explicit  
 REM Define Global Variables  
 DIM Architecture : Set Architecture = Nothing  
 DIM INIFile    : INIFile     = "bldg_premium_full_Relative.ini"  
 DIM InstallFile  : InstallFile   = "setup.exe"  
 DIM TempFolder  : TempFolder    = "c:\temp\"  
 DIM LogFolderName : LogFolderName  = "bldg_premium_full"  
 DIM LogFolder   : LogFolder    = TempFolder & LogFolderName & "\"  
 DIM NewformaExist : NewformaExist  = False  
 DIM RelativePath : Set RelativePath = Nothing  
 REM Define the relative installation path  
 DefineRelativePath()  
 REM Disable File Security Warning  
 DisableWarning()  
 REM Map Drive Letter  
 MapDrive()  
 REM Create the Log Folder  
 CreateLogFolder()  
 REM Install RAC  
 InstallRevit()  
 REM Enable File Security Warning  
 EnableWarning()  
 REM Cleanup Global Memory  
 GlobalMemoryCleanup()  
 '*******************************************************************************  
 '*******************************************************************************  
 Sub DefineRelativePath()  
      REM Get File Name with full relative path  
      RelativePath = WScript.ScriptFullName  
      REM Remove file name, leaving relative path only  
      RelativePath = Left(RelativePath, InStrRev(RelativePath, "\"))  
 End Sub  
 '*******************************************************************************  
 Sub MapDrive()  
      REM Define Local Objects  
      DIM oShell : SET oShell = CreateObject("Wscript.Shell")  
      REM Define Local Variables  
      DIM DeleteDrive  : DeleteDrive  = "net use z: /delete /Y"  
      DIM MapDriveLetter : MapDriveLetter = "net use z:" & Chr(32) & Left(RelativePath, InStrRev(RelativePath, "\")-1)  
      oShell.Run DeleteDrive, 1, True  
      oShell.Run MapDriveLetter, 1, True  
      RelativePath = "z:\"  
      REM Cleanup Local Variables  
      Set DeleteDrive  = Nothing  
      Set MapDriveLetter = Nothing  
      Set oShell     = Nothing  
 End Sub  
 '*******************************************************************************  
 Sub CreateLogFolder()  
      REM Define Local Objects  
      DIM FSO : Set FSO = CreateObject("Scripting.FileSystemObject")  
      If NOT FSO.FolderExists(TempFolder) then  
           FSO.CreateFolder(TempFolder)  
      End If  
      If NOT FSO.FolderExists(LogFolder) then  
           FSO.CreateFolder(LogFolder)  
      End If  
      REM Cleanup Local Variables  
      Set FSO = Nothing  
 End Sub  
 '*******************************************************************************  
 Sub DetermineArchitecture()  
      REM Define Local Objects  
      DIM WshShell : Set WshShell = CreateObject("WScript.Shell")  
      REM Define Local Variables  
      DIM OSType : OSType = WshShell.RegRead("HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\PROCESSOR_ARCHITECTURE")  
      If OSType = "x86" then  
           Architecture = "x86"  
      elseif OSType = "AMD64" then  
           Architecture = "x64"  
      end if  
      REM Cleanup Local Memory  
      Set WshShell = Nothing  
      Set OSType  = Nothing  
 End Sub  
 '*******************************************************************************  
 Sub CheckFreeSpace()  
      REM Define Local Objects  
      DIM oShell : Set oShell = CreateObject( "WScript.Shell" )  
      REM Define Local Variables  
      DIM strComputer : strComputer = "."  
      DIM SystemDrive : SystemDrive = oShell.ExpandEnvironmentStrings("%SystemDrive%")  
      Set objWMIService = GetObject("winmgmts:" _  
           & "{impersonationLevel=impersonate}!\\" _  
           & strComputer & "\root\cimv2")  
      Set colDisks = objWMIService.ExecQuery _  
           ("Select * from Win32_LogicalDisk")  
      For Each objDisk in colDisks  
           If objDisk.DeviceID = SystemDrive then  
                Wscript.Echo "DeviceID: " & objDisk.DeviceID  
                Wscript.Echo "Free Disk Space: " _  
                     & objDisk.FreeSpace  
           End If  
      Next  
      REM Cleanup Local Memory  
      Set oShell   = Nothing  
      Set strComputer = Nothing  
      Set SystemDrive = Nothing  
 End Sub  
 '*******************************************************************************  
 Sub DisableWarning()  
      REM Define Local Objects  
      DIM oShell : Set oShell= CreateObject("Wscript.Shell")  
      DIM oEnv  : Set oEnv = oShell.Environment("PROCESS")  
      oEnv("SEE_MASK_NOZONECHECKS") = 1  
      REM Cleanup Memory  
      Set oShell = Nothing  
      Set oEnv  = Nothing  
 End Sub  
 '*******************************************************************************  
 Sub EnableWarning()  
      REM Define Local Objects  
      DIM oShell : Set oShell= CreateObject("Wscript.Shell")  
      DIM oEnv  : Set oEnv = oShell.Environment("PROCESS")  
      oEnv.Remove("SEE_MASK_NOZONECHECKS")  
      REM Cleanup Memory  
      Set oShell = Nothing  
      Set oEnv  = Nothing  
 End Sub  
 '*******************************************************************************  
 Sub InstallCpp()  
      REM Define Local Objects  
      DIM oShell : SET oShell = CreateObject("Wscript.Shell")  
      REM Define Local Variables  
      DIM Switches : Switches = Chr(32) & "/passive /uninstall /norestart /log" & Chr(32) & LogFolder & "InstallC++.log"  
      DIM Install : Install = RelativePath & "AdminImage\3rdParty\x86\VCRedist\2010\vcredist_x86_NEW.exe" & Switches  
      DIM NoWait  : NoWait  = False  
      DIM Wait   : Wait   = True  
      oShell.Run Install, 1, True  
      REM Cleanup Local Memory  
      Set Switches = Nothing  
      Set Install = Nothing  
      Set NoWait  = Nothing  
      Set oShell  = Nothing  
      Set Wait   = Nothing  
 End Sub  
 '*******************************************************************************  
 Sub UninstallCpp()  
      REM Define Local Objects  
      DIM oShell : SET oShell = CreateObject("Wscript.Shell")  
      REM Define Local Variables  
      DIM Switches  : Switches  = Chr(32) & "/passive /uninstall /norestart /log" & Chr(32) & LogFolder & "UninstallC++.log"  
      DIM Uninstall01 : Uninstall01 = RelativePath & "AdminImage\3rdParty\x86\VCRedist\2010\vcredist_x86.exe" & Switches  
      DIM Uninstall02 : Uninstall02 = RelativePath & "AdminImage\3rdParty\x86\VCRedist\2010\vcredist_x86_NEW.exe" & Switches  
      DIM NoWait   : NoWait = False  
      DIM Wait    : Wait  = True  
      oShell.Run Uninstall01, 1, True  
      oShell.Run Uninstall02, 1, True  
      REM Cleanup Local Memory  
      Set Switches  = Nothing  
      Set Uninstall01 = Nothing  
      Set Uninstall02 = Nothing  
      Set NoWait   = Nothing  
      Set oShell   = Nothing  
      Set Wait    = Nothing  
 End Sub  
 '*******************************************************************************  
 Sub InstallRevit()  
      REM Define Local Objects  
      DIM oShell : SET oShell = CreateObject("Wscript.Shell")  
      REM Define Local Variables  
      DIM Switches : Switches = Chr(32) & "/qb /I" & Chr(32) & RelativePath & "AdminImage\" & INIFile & Chr(32) & "/language en-us"  
      DIM Install : Install = RelativePath & "AdminImage\" & InstallFile & Switches  
      DIM NoWait  : NoWait  = False  
      DIM Wait   : Wait   = True  
      oShell.Run Install, 1, True  
      Call WaitForInstall()  
      REM Cleanup Local Variables  
      Set Install = Nothing  
      Set NoWait  = Nothing  
      Set oShell  = Nothing  
      Set Switches = Nothing  
      Set Wait   = Nothing  
 End Sub  
 '*******************************************************************************  
 Sub WaitForInstall()  
      REM Define Local Constants  
      CONST Timeout = 3000  
      CONST Timepoll = 500  
      REM Define Local Variables  
      DIM sQuery : sQuery = "select * from win32_process where name=" & Chr(39) & InstallFile & Chr(39)  
      DIM SVC  : Set SVC = GetObject("winmgmts:root\cimv2")  
      REM Define Local Variables  
      DIM cproc  : Set cproc  = Nothing  
      DIM iniproc : Set iniproc = Nothing  
      REM Wait until Second Setup.exe closes  
      Wscript.Sleep 30000  
      Set cproc = svc.execquery(sQuery)  
      iniproc = cproc.count  
      Do While iniproc = 1  
           wscript.sleep 5000  
           set svc=getobject("winmgmts:root\cimv2")  
           sQuery = "select * from win32_process where name=" & Chr(39) & InstallFile & Chr(39)  
           set cproc=svc.execquery(sQuery)  
           iniproc=cproc.count  
      Loop  
      REM Cleanup Local Variables  
      Set cproc  = Nothing  
      Set iniproc = Nothing  
      Set sQuery = Nothing  
      set SVC   = Nothing  
 End Sub  
 '*******************************************************************************  
 Sub GlobalMemoryCleanup()  
      REM Define Local Objects  
      DIM oShell : SET oShell = CreateObject("Wscript.Shell")  
      REM Define Local Variables  
      DIM DeleteDrive : DeleteDrive = "net use z: /delete /Y"  
      oShell.Run DeleteDrive, 1, True  
      Set Architecture = Nothing  
      Set INIFile    = Nothing  
      Set InstallFile  = Nothing  
      Set LogFolder   = Nothing  
      Set LogFolderName = Nothing  
      Set RelativePath = Nothing  
      Set TempFolder  = Nothing  
      REM Cleanup Local Memory  
      Set DeleteDrive = Nothing  
      Set oShell   = Nothing  
 End Sub  

16 July 2013

SCCM: Initiate Hardware Inventory from an application package

You have setup an application package and want to initiate a hardware inventory immediately after the software is installed. Here is a powershell script that will initiate the hardware inventory, verify it was initiated and return an error code 0 if initiated back to SCCM. This allows the hardware inventory to become an application with a return value to look for by injecting the script in as a custom script as the detection method.

You can download the script from here to inject into SCCM.


 Clear-Host  
 Set-Variable -Name a -Scope Global -Force  
 Set-Variable -Name SMSCli -Scope Global -Force  
 $SMSCli = [wmiclass] "root\ccm:SMS_Client"  
 $a = $SMSCli.TriggerSchedule("{00000000-0000-0000-0000-000000000001}")  
 If ($a.__PROPERTY_COUNT -eq 1) {  
      $SMSCli.Dispose  
      Remove-Variable -Name a -Scope Global -Force  
      Remove-Variable -Name SMSCli -Scope Global -Force  
      exit 0  
 } else {  
      $SMSCli.Dispose  
      Remove-Variable -Name a -Scope Global -Force  
      Remove-Variable -Name SMSCli -Scope Global -Force  
      exit 1  
 }  

Powershell: Autodesk Revit 2013 Building Premium Uninstall Script

Here is a script I have written that will uninstall Revit 2013 Building Premium. Autodesk provides the Design Suite uninstall tool, but it does not uninstall all of the components. This script I have written does.

You can download the script from here.

 cls  
 Function AutoCAD2013English{  
      #Declare Local Memory  
      Set-Variable -Name GUID -Value "{5783F2D7-B001-0000-0102-0060B0CE6BBA}" -Scope Local -Force  
      Set-Variable -Name Arguments -Scope Local -Force  
      Write-Host "AutoCAD 2013 - English"  
      $Arguments = "/X"+[char]32+$GUID+[char]32+"/qb- /norestart"  
      (Start-Process -FilePath "msiexec.exe" -ArgumentList $Arguments -Wait -Passthru).ExitCode  
      #Cleanup Local Memory  
      Remove-Variable -Name GUID -Scope Local -Force  
      Remove-Variable -Name Arguments -Scope Local -Force  
 }  
 Function AutodeskRevitInteroperabilityfor3dsMaxand3dsMaxDesign201364-bit{  
      #Declare Local Memory  
      Set-Variable -Name GUID -Value "{06E18300-BB64-1664-8E6A-2593FC67BB74}" -Scope Local -Force  
      Set-Variable -Name Arguments -Scope Local -Force  
      Write-Host "Autodesk Revit Interoperability for 3ds Max and 3ds Max Design 2013 64-bit"  
      $Arguments = "/X"+[char]32+$GUID+[char]32+"/qb- /norestart"  
      (Start-Process -FilePath "msiexec.exe" -ArgumentList $Arguments -Wait -Passthru).ExitCode  
      #Cleanup Local Memory  
      Remove-Variable -Name GUID -Scope Local -Force  
      Remove-Variable -Name Arguments -Scope Local -Force  
 }  
 Function AutodeskShowcase201364-bit{  
      #Declare Local Memory  
      Set-Variable -Name GUID -Value "{A15BFC7D-6A90-47E6-8C6E-D51B2929D8C8}" -Scope Local -Force  
      Set-Variable -Name Arguments -Scope Local -Force  
      Write-Host "Autodesk Showcase 2013 64-bit"  
      $Arguments = "/X"+[char]32+$GUID+[char]32+"/qb- /norestart"  
      (Start-Process -FilePath "msiexec.exe" -ArgumentList $Arguments -Wait -Passthru).ExitCode  
      #Cleanup Local Memory  
      Remove-Variable -Name GUID -Scope Local -Force  
      Remove-Variable -Name Arguments -Scope Local -Force  
 }  
 Function AutodeskDirectConnect201364-bit{  
      #Declare Local Memory  
      Set-Variable -Name GUID -Value "{324297F8-2898-454B-9AC4-07050AEB35B3}" -Scope Local -Force  
      Set-Variable -Name Arguments -Scope Local -Force  
      Write-Host "Autodesk DirectConnect 2013 64-bit"  
      $Arguments = "/X"+[char]32+$GUID+[char]32+"/qb- /norestart"  
      (Start-Process -FilePath "msiexec.exe" -ArgumentList $Arguments -Wait -Passthru).ExitCode  
      #Cleanup Local Memory  
      Remove-Variable -Name GUID -Scope Local -Force  
      Remove-Variable -Name Arguments -Scope Local -Force  
 }  
 Function AutodeskSketchBookDesigner2013{  
      #Declare Local Memory  
      Set-Variable -Name GUID -Value "{3CB60177-D3D2-4E9C-BE4D-8372B34B4C7F}" -Scope Local -Force  
      Set-Variable -Name Arguments -Scope Local -Force  
      Write-Host "Autodesk SketchBook Designer 2013"  
      $Arguments = "/X"+[char]32+$GUID+[char]32+"/qb- /norestart"  
      (Start-Process -FilePath "msiexec.exe" -ArgumentList $Arguments -Wait -Passthru).ExitCode  
      #Cleanup Local Memory  
      Remove-Variable -Name GUID -Scope Local -Force  
      Remove-Variable -Name Arguments -Scope Local -Force  
 }  
 Function AutodeskDesignReview201332-bit{  
      #Declare Local Memory  
      Set-Variable -Name GUID -Value "{153DB567-6FF3-49AD-AC4F-86F8A3CCFDFB}" -Scope Local -Force  
      Set-Variable -Name Arguments -Scope Local -Force  
      Write-Host "Autodesk Design Review 2013 *32-bit*"  
      $Arguments = "/X"+[char]32+$GUID+[char]32+"/qb- /norestart"  
      (Start-Process -FilePath "msiexec.exe" -ArgumentList $Arguments -Wait -Passthru).ExitCode  
      #Cleanup Local Memory  
      Remove-Variable -Name GUID -Scope Local -Force  
      Remove-Variable -Name Arguments -Scope Local -Force  
 }  
 Function AutodeskInventorFusion2013{  
      #Declare Local Memory  
      Set-Variable -Name GUID -Value "{FFF5619F-2013-0064-A85E-9994F70A9E5D}" -Scope Local -Force  
      Set-Variable -Name Arguments -Scope Local -Force  
      Write-Host "Autodesk Inventor Fusion 2013"  
      $Arguments = "/X"+[char]32+$GUID+[char]32+"/qb- /norestart"  
      (Start-Process -FilePath "msiexec.exe" -ArgumentList $Arguments -Wait -Passthru).ExitCode  
      #Cleanup Local Memory  
      Remove-Variable -Name GUID -Scope Local -Force  
      Remove-Variable -Name Arguments -Scope Local -Force  
 }  
 Function AutodeskMaterialLibrary201332-bit{  
      #Declare Local Memory  
      Set-Variable -Name GUID -Value "{117EBEEB-5DB0-43C8-9FD6-DD583DB152DD}" -Scope Local -Force  
      Set-Variable -Name Arguments -Scope Local -Force  
      Write-Host "Autodesk Material Library 2013 *32-bit*"  
      $Arguments = "/X"+[char]32+$GUID+[char]32+"/qb- /norestart"  
      (Start-Process -FilePath "msiexec.exe" -ArgumentList $Arguments -Wait -Passthru).ExitCode  
      #Cleanup Local Memory  
      Remove-Variable -Name GUID -Scope Local -Force  
      Remove-Variable -Name Arguments -Scope Local -Force  
 }  
 Function AutodeskMaterialLibraryBaseResolutionImageLibrary2013{  
      #Declare Local Memory  
      Set-Variable -Name GUID -Value "{606E12B9-641F-4644-A22A-FF38AE980AFD}" -Scope Local -Force  
      Set-Variable -Name Arguments -Scope Local -Force  
      Write-Host "Autodesk Material Library Base Resolution Image Library 2013"  
      $Arguments = "/X"+[char]32+$GUID+[char]32+"/qb- /norestart"  
      (Start-Process -FilePath "msiexec.exe" -ArgumentList $Arguments -Wait -Passthru).ExitCode  
      #Cleanup Local Memory  
      Remove-Variable -Name GUID -Scope Local -Force  
      Remove-Variable -Name Arguments -Scope Local -Force  
 }  
 Function AutodeskMaterialLibraryLowResolutionImageLibrary2013{  
      #Declare Local Memory  
      Set-Variable -Name GUID -Value "{27C6C0A2-2EC9-4FEA-BE2B-659EAAC2C68C}" -Scope Local -Force  
      Set-Variable -Name Arguments -Scope Local -Force  
      Write-Host "Autodesk Material Library Low Resolution Image Library 2013"  
      $Arguments = "/X"+[char]32+$GUID+[char]32+"/qb- /norestart"  
      (Start-Process -FilePath "msiexec.exe" -ArgumentList $Arguments -Wait -Passthru).ExitCode  
      #Cleanup Local Memory  
      Remove-Variable -Name GUID -Scope Local -Force  
      Remove-Variable -Name Arguments -Scope Local -Force  
 }  
 Function AutodeskMaterialLibraryMediumResolutionImageLibrary2013{  
      #Declare Local Memory  
      Set-Variable -Name GUID -Value "{58760EEC-8B6A-43F4-81AA-696E381DFADD}" -Scope Local -Force  
      Set-Variable -Name Arguments -Scope Local -Force  
      Write-Host "Autodesk Material Library Medium Resolution Image Library 2013"  
      $Arguments = "/X"+[char]32+$GUID+[char]32+"/qb- /norestart"  
      (Start-Process -FilePath "msiexec.exe" -ArgumentList $Arguments -Wait -Passthru).ExitCode  
      #Cleanup Local Memory  
      Remove-Variable -Name GUID -Scope Local -Force  
      Remove-Variable -Name Arguments -Scope Local -Force  
 }  
 Function AutodeskContentService{  
      #Declare Local Memory  
      Set-Variable -Name GUID -Value "{62F029AB-85F2-0000-866A-9FC0DD99DDBC}" -Scope Local -Force  
      Set-Variable -Name Arguments -Scope Local -Force  
      Write-Host "Autodesk Content Service"  
      $Arguments = "/X"+[char]32+$GUID+[char]32+"/qb- /norestart"  
      (Start-Process -FilePath "msiexec.exe" -ArgumentList $Arguments -Wait -Passthru).ExitCode  
      #Cleanup Local Memory  
      Remove-Variable -Name GUID -Scope Local -Force  
      Remove-Variable -Name Arguments -Scope Local -Force  
 }  
 Function AutodeskSync{  
      #Declare Local Memory  
      Set-Variable -Name GUID -Value "{EE5F74BC-5CD5-4EF2-86BA-81E6CF46A18F}" -Scope Local -Force  
      Set-Variable -Name Arguments -Scope Local -Force  
      Write-Host "Autodesk Sync"  
      $Arguments = "/X"+[char]32+$GUID+[char]32+"/qb- /norestart"  
      (Start-Process -FilePath "msiexec.exe" -ArgumentList $Arguments -Wait -Passthru).ExitCode  
      #Cleanup Local Memory  
      Remove-Variable -Name GUID -Scope Local -Force  
      Remove-Variable -Name Arguments -Scope Local -Force  
 }  
 Function AutodeskRevit2013{  
      #Declare Local Memory  
      Set-Variable -Name GUID -Value "{7346B4A0-1300-0510-0409-705C0D862004}" -Scope Local -Force  
      Set-Variable -Name Arguments -Scope Local -Force  
      Write-Host "Autodesk Revit 2013"  
      $Arguments = "/X"+[char]32+$GUID+[char]32+"/qb- /norestart"  
      (Start-Process -FilePath "msiexec.exe" -ArgumentList $Arguments -Wait -Passthru).ExitCode  
      #Cleanup Local Memory  
      Remove-Variable -Name GUID -Scope Local -Force  
      Remove-Variable -Name Arguments -Scope Local -Force  
 }  
 Function AutoCADArchitecture2013{  
      #Declare Local Memory  
      Set-Variable -Name GUID -Value "{5783F2D7-B004-0000-0102-0060B0CE6BBA}" -Scope Local -Force  
      Set-Variable -Name Arguments -Scope Local -Force  
      Write-Host "AutoCAD Architecture 2013"  
      $Arguments = "/X"+[char]32+$GUID+[char]32+"/qb- /norestart"  
      (Start-Process -FilePath "msiexec.exe" -ArgumentList $Arguments -Wait -Passthru).ExitCode  
      #Cleanup Local Memory  
      Remove-Variable -Name GUID -Scope Local -Force  
      Remove-Variable -Name Arguments -Scope Local -Force  
 }  
 Function AutodeskNavisworksSimulate2013{  
      #Declare Local Memory  
      Set-Variable -Name GUID -Value "{F17E30E2-7ED4-0000-8A8E-CAB597E3F8ED}" -Scope Local -Force  
      Set-Variable -Name Arguments -Scope Local -Force  
      Write-Host "Autodesk Navisworks Simulate 2013"  
      $Arguments = "/X"+[char]32+$GUID+[char]32+"/qb- /norestart"  
      (Start-Process -FilePath "msiexec.exe" -ArgumentList $Arguments -Wait -Passthru).ExitCode  
      #Cleanup Local Memory  
      Remove-Variable -Name GUID -Scope Local -Force  
      Remove-Variable -Name Arguments -Scope Local -Force  
 }  
 Function AutodeskWorkflowsBuildingDesignSuite2013{  
      #Declare Local Memory  
      Set-Variable -Name GUID -Value "{06388E0D-A364-478B-8E40-7D76142A8DF2}" -Scope Local -Force  
      Set-Variable -Name Arguments -Scope Local -Force  
      Write-Host "Autodesk Workflows - Building Design Suite 2013"  
      $Arguments = "/X"+[char]32+$GUID+[char]32+"/qb- /norestart"  
      (Start-Process -FilePath "msiexec.exe" -ArgumentList $Arguments -Wait -Passthru).ExitCode  
      #Cleanup Local Memory  
      Remove-Variable -Name GUID -Scope Local -Force  
      Remove-Variable -Name Arguments -Scope Local -Force  
 }  
 Function AutodeskNavisworksSimulate20132008DWGFileReader{  
      #Declare Local Memory  
      Set-Variable -Name GUID -Value "{4F744A9A-3067-4605-8864-DA1658059F0B}" -Scope Local -Force  
      Set-Variable -Name Arguments -Scope Local -Force  
      Write-Host "Autodesk Navisworks Simulate 2013 - 2008 DWG File Reader"  
      $Arguments = "/X"+[char]32+$GUID+[char]32+"/qb- /norestart"  
      (Start-Process -FilePath "msiexec.exe" -ArgumentList $Arguments -Wait -Passthru).ExitCode  
      #Cleanup Local Memory  
      Remove-Variable -Name GUID -Scope Local -Force  
      Remove-Variable -Name Arguments -Scope Local -Force  
 }  
 Function AutodeskNavisworksSimulate20132009DWGFileReader{  
      #Declare Local Memory  
      Set-Variable -Name GUID -Value "{07DC9A9D-1793-4EB4-AC1A-70750F9FB72B}" -Scope Local -Force  
      Set-Variable -Name Arguments -Scope Local -Force  
      Write-Host "Autodesk Navisworks Simulate 2013 - 2009 DWG File Reader"  
      $Arguments = "/X"+[char]32+$GUID+[char]32+"/qb- /norestart"  
      (Start-Process -FilePath "msiexec.exe" -ArgumentList $Arguments -Wait -Passthru).ExitCode  
      #Cleanup Local Memory  
      Remove-Variable -Name GUID -Scope Local -Force  
      Remove-Variable -Name Arguments -Scope Local -Force  
 }  
 Function AutodeskNavisworksSimulate20132010DWGFileReader{  
      #Declare Local Memory  
      Set-Variable -Name GUID -Value "{0D53A298-B2B7-4746-BB92-B757A6E559C3}" -Scope Local -Force  
      Set-Variable -Name Arguments -Scope Local -Force  
      Write-Host "Autodesk Navisworks Simulate 2013 - 2010 DWG File Reader"  
      $Arguments = "/X"+[char]32+$GUID+[char]32+"/qb- /norestart"  
      (Start-Process -FilePath "msiexec.exe" -ArgumentList $Arguments -Wait -Passthru).ExitCode  
      #Cleanup Local Memory  
      Remove-Variable -Name GUID -Scope Local -Force  
      Remove-Variable -Name Arguments -Scope Local -Force  
 }  
 Function AutodeskNavisworksSimulate20132011DWGFileReader{  
      #Declare Local Memory  
      Set-Variable -Name GUID -Value "{107CB1E9-DDA9-40B5-8A6D-325361402200}" -Scope Local -Force  
      Set-Variable -Name Arguments -Scope Local -Force  
      Write-Host "Autodesk Navisworks Simulate 2013 - 2011 DWG File Reader"  
      $Arguments = "/X"+[char]32+$GUID+[char]32+"/qb- /norestart"  
      (Start-Process -FilePath "msiexec.exe" -ArgumentList $Arguments -Wait -Passthru).ExitCode  
      #Cleanup Local Memory  
      Remove-Variable -Name GUID -Scope Local -Force  
      Remove-Variable -Name Arguments -Scope Local -Force  
 }  
 Function Revit2013LanguagePackEnglish{  
      #Declare Local Memory  
      Set-Variable -Name GUID -Value "{7346B4A0-1300-0511-0409-705C0D862004}" -Scope Local -Force  
      Set-Variable -Name Arguments -Scope Local -Force  
      Write-Host "Revit 2013 Language Pack - English"  
      $Arguments = "/X"+[char]32+$GUID+[char]32+"/qb- /norestart"  
      (Start-Process -FilePath "msiexec.exe" -ArgumentList $Arguments -Wait -Passthru).ExitCode  
      #Cleanup Local Memory  
      Remove-Variable -Name GUID -Scope Local -Force  
      Remove-Variable -Name Arguments -Scope Local -Force  
 }  
 Function AutodeskNavisworksSimulate20132012DWGFileReader{  
      #Declare Local Memory  
      Set-Variable -Name GUID -Value "{90A2F9D3-3E5E-4EF4-BC83-E7795CEF1A42}" -Scope Local -Force  
      Set-Variable -Name Arguments -Scope Local -Force  
      Write-Host "Autodesk Navisworks Simulate 2013 - 2012 DWG File Reader"  
      $Arguments = "/X"+[char]32+$GUID+[char]32+"/qb- /norestart"  
      (Start-Process -FilePath "msiexec.exe" -ArgumentList $Arguments -Wait -Passthru).ExitCode  
      #Cleanup Local Memory  
      Remove-Variable -Name GUID -Scope Local -Force  
      Remove-Variable -Name Arguments -Scope Local -Force  
 }  
 Function AutodeskNavisworksSimulate20132013DWGFileReader{  
      #Declare Local Memory  
      Set-Variable -Name GUID -Value "{CBED6FC7-FB20-4920-AA80-3D6F3459F902}" -Scope Local -Force  
      Set-Variable -Name Arguments -Scope Local -Force  
      Write-Host "Autodesk Navisworks Simulate 2013 - 2013 DWG File Reader"  
      $Arguments = "/X"+[char]32+$GUID+[char]32+"/qb- /norestart"  
      (Start-Process -FilePath "msiexec.exe" -ArgumentList $Arguments -Wait -Passthru).ExitCode  
      #Cleanup Local Memory  
      Remove-Variable -Name GUID -Scope Local -Force  
      Remove-Variable -Name Arguments -Scope Local -Force  
 }  
 Function AutodeskNavisworksSimulate2013EnglishLanguagePack{  
      #Declare Local Memory  
      Set-Variable -Name GUID -Value "{F17E30E2-7ED4-0409-8A8E-CAB597E3F8ED}" -Scope Local -Force  
      Set-Variable -Name Arguments -Scope Local -Force  
      Write-Host "Autodesk Navisworks Simulate 2013 English Language Pack"  
      $Arguments = "/X"+[char]32+$GUID+[char]32+"/qb- /norestart"  
      (Start-Process -FilePath "msiexec.exe" -ArgumentList $Arguments -Wait -Passthru).ExitCode  
      #Cleanup Local Memory  
      Remove-Variable -Name GUID -Scope Local -Force  
      Remove-Variable -Name Arguments -Scope Local -Force  
 }  
 Function AutodeskSimulationCFD2013{  
      #Declare Local Memory  
      Set-Variable -Name GUID -Value "{1C11BFF1-1FA3-4AA9-AA15-9AA2BB921F9E}" -Scope Local -Force  
      Set-Variable -Name Arguments -Scope Local -Force  
      Write-Host "Autodesk Simulation CFD 2013"  
      $Arguments = "/X"+[char]32+$GUID+[char]32+"/qb- /norestart"  
      (Start-Process -FilePath "msiexec.exe" -ArgumentList $Arguments -Wait -Passthru).ExitCode  
      #Cleanup Local Memory  
      Remove-Variable -Name GUID -Scope Local -Force  
      Remove-Variable -Name Arguments -Scope Local -Force  
 }  
 #Covers all apps the ADSUninstallTool.exe uninstalls  
 AutoCAD2013English  
 AutodeskRevitInteroperabilityfor3dsMaxand3dsMaxDesign201364-bit  
 AutodeskShowcase201364-bit  
 AutodeskDirectConnect201364-bit  
 AutodeskSketchBookDesigner2013  
 AutodeskDesignReview201332-bit  
 AutodeskInventorFusion2013  
 AutodeskMaterialLibrary201332-bit  
 AutodeskMaterialLibraryBaseResolutionImageLibrary2013  
 AutodeskMaterialLibraryLowResolutionImageLibrary2013  
 AutodeskMaterialLibraryMediumResolutionImageLibrary2013  
 AutodeskContentService  
 AutodeskSync  
 #Uninstalls the ADSUninstallTool.exe does not uninstall  
 AutodeskRevit2013  
 AutoCADArchitecture2013  
 AutodeskNavisworksSimulate2013  
 AutodeskWorkflowsBuildingDesignSuite2013  
 AutodeskNavisworksSimulate20132008DWGFileReader  
 AutodeskNavisworksSimulate20132009DWGFileReader  
 AutodeskNavisworksSimulate20132010DWGFileReader  
 AutodeskNavisworksSimulate20132011DWGFileReader  
 Revit2013LanguagePackEnglish  
 AutodeskNavisworksSimulate20132012DWGFileReader  
 AutodeskNavisworksSimulate20132013DWGFileReader  
 AutodeskNavisworksSimulate2013EnglishLanguagePack  
 AutodeskSimulationCFD2013  

15 July 2013

Powershell: How to verify if a Windows Feature is enabled or disabled in a script

I recently wanted to add the feature to MDT to be able to verify if a Windows feature is enabled or disabled, and then write a registry key for MDT. This is an example I use here to disable MediaCenter in Windows 7 and then register that in Add/Remove Programs.

You can download the script from here

 cls  

 #Declare Global Memory  
 Set-Variable -Name a -Scope Global -Force  
 Set-Variable -Name Output -Scope Global -Force  

 Function AddRemovePrograms($KeyName, $DisplayName, $Version){  
      #Declare Local Memory  
      Set-Variable -Name AddRemKey -Value "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" -Scope Local -Force  

      New-Item -Path $AddRemKey -Name $KeyName –Force  
      New-ItemProperty -Path $AddRemKey"\"$KeyName -Name DisplayName -Value $DisplayName -PropertyType String  
      New-ItemProperty -Path $AddRemKey"\"$KeyName -Name DisplayVersion -Value $Version -PropertyType String  
      New-ItemProperty -Path $AddRemKey"\"$KeyName -Name UninstallString -Value " " -PropertyType String  
      New-ItemProperty -Path $AddRemKey"\"$KeyName -Name Publisher -Value "Gresham, Smith and Partners" -PropertyType String  
      New-ItemProperty -Path $AddRemKey"\"$KeyName -Name DisplayIcon -Value "c:\windows\GSPBox_Icon.bmp" -PropertyType String  

      #Cleanup Local Memory  
      Remove-Variable -Name AddRemKey -Scope Local -Force  
 }  
 Invoke-Command {dism.exe /online /disable-feature /featurename:MediaCenter /norestart}  
 $a = Invoke-Command {dism.exe /online /get-featureinfo /featurename:MediaCenter}  
 $Output = $a | Select-String "State : Disabled"  
 Write-Host $Output  
 If ($Output -like "State : Disabled"){  
      AddRemovePrograms "MediaCenter" "MediaCenter" "Disabled"  
 }  

 #Cleanup Global Memory  
 Remove-Variable -Name a -Scope Global -Force  
 Remove-Variable -Name Output -Scope Global -Force  

02 July 2013

SCCM: Properties Window Follows Mouse

This was an observation I noticed today. If you have multiple monitors, when you open up the properties window of an SCCM object, the window will open up on the monitor that your cursor is residing. 

01 July 2013

SCCM: How to export a list of machines from the Deployment Status Window

Sometimes when checking the status of a deployment, you will need to export a list of machines from one of the asset details list. In the SCCM deployment status  window, it is not possible. In order to export the list, you will need to go to the reports section, where exporting is available. Take this deployment I was doing for instance. There were 11 machines that failed the evaluation phase. I needed the list of machines from that report to run a powershell script to see if the hotfix was installed or not. I was going to run the script through psexec against a text file containing that list of machines.


In order to export the list of machines, you will need to go to Reporting. I use the web based reporting. Under Reporting, click on Software Distribution - Application Monitoring--->All application deployments. Populate the fields to match the collection you are wishing to export. This will match the Deployments Status in the console. Once you have pulled the report up, click on View Current Data. Under the next window, click on the Total Number of Errors, for instance. Next, click on the assets field to select the report to export. This is where you can now export the list of machines.

28 June 2013

Apply all Microsoft Office Updates within a folder

Here is a script that will install all Microsoft Office updates within the same folder. It queries the folder for all of the filenames and then runs installs the updates.

You can download the script from here.

 '*******************************************************************************  
 '   Author: Mick Pletcher  
 '    Date: 28 June 2013  
 '  Modified:  
 '  
 ' Description: This will install all office updates residing in the same folder as this  
 '                 script.  
 '                 1) Define the relative installation path  
 '                 2) Create the Log Folder  
 '                 3) Read list of Updates into Array  
 '                 4) Install updates  
 '                 5) Cleanup Global Memory  
 '*******************************************************************************  

 Option Explicit  

 REM Define Constants  
 CONST TempFolder    = "c:\temp\"  
 CONST LogFolderName = "OfficeUpdates"  

 REM Define Global Variables  
 DIM Count        : Count      = 1  
 DIM LogFolder    : LogFolder    = TempFolder & LogFolderName & "\"  
 DIM RelativePath : Set RelativePath = Nothing  
 ReDIM arrFiles(1)  

 REM Define the relative installation path  
 DefineRelativePath()  
 REM Create the Log Folder  
 CreateLogFolder()  
 REM Read list of Updates into Array  
 ReadUpdates()  
 REM Install Updates  
 InstallUpdates()  
 REM Cleanup Global Memory  
 GlobalMemoryCleanup()  

 '*******************************************************************************  
 '*******************************************************************************  

 Sub DefineRelativePath()  

      REM Get File Name with full relative path  
      RelativePath = WScript.ScriptFullName  
      REM Remove file name, leaving relative path only  
      RelativePath = Left(RelativePath, InStrRev(RelativePath, "\"))  

 End Sub  

 '*******************************************************************************  

 Sub CreateLogFolder()  

      REM Define Local Objects  
      DIM FSO : Set FSO = CreateObject("Scripting.FileSystemObject")  

      If NOT FSO.FolderExists(TempFolder) then  
           FSO.CreateFolder(TempFolder)  
      End If  
      If NOT FSO.FolderExists(LogFolder) then  
           FSO.CreateFolder(LogFolder)  
      End If  

      REM Cleanup Local Variables  
      Set FSO = Nothing  

 End Sub  

 '*******************************************************************************  

 Sub ReadUpdates()  

      REM Define Local Objects  
      DIM FSO : Set FSO = CreateObject("Scripting.FileSystemObject")  

      REM Define Local Variables  
      DIM Folder : Set Folder = FSO.GetFolder(RelativePath)  
      DIM Files  : Set files = Folder.Files  
      DIM File   : Set File  = Nothing  

      For each File in Files  
           If NOT File.Name = Wscript.ScriptName then  
                arrFiles(Count) = File.Name  
                Count = Count + 1  
                ReDim Preserve arrFiles(Count)  
           End If  
      Next  
      Count = Count - 1  

      REM Cleanup Local Memory  
      Set File   = Nothing  
      Set Files  = Nothing  
      Set Folder = Nothing  
      Set FSO    = Nothing  

 End Sub  

 '*******************************************************************************  

 Sub InstallUpdates()  

      REM Define Local Objects  
      DIM File     : Set File   = Nothing  
      DIM FSO      : Set FSO   = CreateObject("Scripting.FileSystemObject")  
      DIM i        : Set i    = Nothing  
      DIM oShell   : Set oShell  = CreateObject("Wscript.Shell")  
      DIM Switches : Set Switches = Nothing  

      For i = 1 to Count  
           File = Left(arrFiles(i),Len(arrFiles(i))-4)  
           Switches = Chr(32) & "/passive /norestart /log:" & LogFolder & File & ".log"  
           oShell.run arrFiles(i) & Switches, 1, True  
      Next  

      REM Cleanup Local Memory  
      Set File     = Nothing  
      Set FSO      = Nothing  
      Set i        = Nothing  
      Set oShell   = Nothing  
      Set Switches = Nothing  

 End Sub  

 '*******************************************************************************  

 Sub GlobalMemoryCleanup()  

      Set Count        = Nothing  
      Set LogFolder    = Nothing  
      Set RelativePath = Nothing  
      Erase arrFiles  

 End Sub  

17 June 2013

How to extract the iOS 7 ipsw file from the dmg on a PC and apply it to your iDevice

First thing to do is to download the DMG file from Apple. Once you have downloaded it, here is how to push it to your iPhone


  1. Extract the .IPSW file from the DMG. I used PeaZIP to open up the DMG file. Once you open it up, double-click on 2.hfs. the IPSW file is located inside of it.
  2. Open up iTunes
  3. Connect your iPhone/iPod/iPad to the PC
  4. In iTunes, click on the device in the upper right corner
  5. Make sure you perform a backup of your device. I a backup both to iCloud and my PC.
  6. While holding down the shift key, click on Restore iPod/iPad/iPhone
  7. Select the IPSW file to apply to the device
That is all that is to it.

12 June 2013

Autodesk Revit 2013 Hotfix Script

Here is a script that will automate the installation of the new DLL files that replace the old ones. Sadly, Autodesk expects for all users to manually replace these files, even in larger corporations, like I work in. This script runs relative to to it's execution path. The only thing that has to be done is to make sure all of the DLL files are in the same directory, including the directory .\RevitServerToolCommand be present, containing the DLL files within that directory too.

Here is the link to Autodesk's website describing what this script does.

Here is the link to download the script below.

 #*******************************************************************************  
 #   Author: Mick Pletcher  
 #    Date: 12 June 2013  
 #  
 #   Program: Revit 2013 Hotfix  
 #*******************************************************************************  
 Clear-Host  

 $Global:OS  
 $Global:RelativePath  
 $FileLoc = "C:\Program Files\Autodesk\Revit 2013\Program\"  
 $DLL_01 = "RS.Common.ClientServer.Proxy"  
 $DLL_02 = "DataStorageClient"  
 $DLL_03 = "DesktopMFC"  
 $DLL_04 = "FamilyDB"  
 $DLL_05 = "GeomUtil"  
 $DLL_06 = "Graphics"  
 $DLL_07 = "GrphOGS3"  
 $DLL_08 = "CommandServiceClient"  
 $DLL_09 = "RS.Common.ClientServer.Proxy"  

 Function GetRelativePath{  
      $Global:RelativePath=(split-path $SCRIPT:MyInvocation.MyCommand.Path -parent)+"\"  
      Write-Host $Global:RelativePath  
 }  

 Function GetOSArchitecture{  
      $Global:OS=Get-WMIObject win32_operatingsystem  
      #$Global:OS.OSArchitecture  
      #Answers: 32-bit, 64-bit  
 }  

 GetRelativePath  
 GetOSArchitecture  
 If ($Global:OS.OSArchitecture -eq "64-bit"){  
      If ((Test-Path -Path $FileLoc$DLL_01".dll") -eq $true){  
           Copy-Item -Path $FileLoc$DLL_01".dll" -Destination $FileLoc$DLL_01".orig" -Force  
           Remove-Item -Path $FileLoc$DLL_01".dll" -Force  
           Copy-Item -Path $Global:RelativePath$DLL_01".dll" -Destination $FileLoc -Force  
      }  
      If ((Test-Path -Path $FileLoc$DLL_02".dll") -eq $true){  
           Copy-Item -Path $FileLoc$DLL_02".dll" -Destination $FileLoc$DLL_02".orig" -Force  
           Remove-Item -Path $FileLoc$DLL_02".dll" -Force  
           Copy-Item -Path $Global:RelativePath$DLL_02".dll" -Destination $FileLoc -Force  
      }  
      If ((Test-Path -Path $FileLoc$DLL_03".dll") -eq $true){  
           Copy-Item -Path $FileLoc$DLL_03".dll" -Destination $FileLoc$DLL_03".orig" -Force  
           Remove-Item -Path $FileLoc$DLL_03".dll" -Force  
           Copy-Item -Path $Global:RelativePath$DLL_03".dll" -Destination $FileLoc -Force  
      }  
      If ((Test-Path -Path $FileLoc$DLL_04".dll") -eq $true){  
           Copy-Item -Path $FileLoc$DLL_04".dll" -Destination $FileLoc$DLL_04".orig" -Force  
           Remove-Item -Path $FileLoc$DLL_04".dll" -Force  
           Copy-Item -Path $Global:RelativePath$DLL_04".dll" -Destination $FileLoc -Force  
      }  
      If ((Test-Path -Path $FileLoc$DLL_05".dll") -eq $true){  
           Copy-Item -Path $FileLoc$DLL_05".dll" -Destination $FileLoc$DLL_05".orig" -Force  
           Remove-Item -Path $FileLoc$DLL_05".dll" -Force  
           Copy-Item -Path $Global:RelativePath$DLL_05".dll" -Destination $FileLoc -Force  
      }  
      If ((Test-Path -Path $FileLoc$DLL_06".dll") -eq $true){  
           Copy-Item -Path $FileLoc$DLL_06".dll" -Destination $FileLoc$DLL_06".orig" -Force  
           Remove-Item -Path $FileLoc$DLL_06".dll" -Force  
           Copy-Item -Path $Global:RelativePath$DLL_06".dll" -Destination $FileLoc -Force  
      }  
      If ((Test-Path -Path $FileLoc$DLL_07".dll") -eq $true){  
           Copy-Item -Path $FileLoc$DLL_07".dll" -Destination $FileLoc$DLL_07".orig" -Force  
           Remove-Item -Path $FileLoc$DLL_07".dll" -Force  
           Copy-Item -Path $Global:RelativePath$DLL_07".dll" -Destination $FileLoc -Force  
      }  
      If ((Test-Path -Path $FileLoc"RevitServerToolCommand\"$DLL_08".dll") -eq $true){  
           Copy-Item -Path $FileLoc"RevitServerToolCommand\"$DLL_08".dll" -Destination $FileLoc"RevitServerToolCommand\"$DLL_08".orig" -Force  
           Remove-Item -Path $FileLoc"RevitServerToolCommand\"$DLL_08".dll" -Force  
           Copy-Item -Path $Global:RelativePath"RevitServerToolCommand\"$DLL_08".dll" -Destination $FileLoc"RevitServerToolCommand\" -Force  
      }  
      If ((Test-Path -Path $FileLoc"RevitServerToolCommand\"$DLL_09".dll") -eq $true){  
           Copy-Item -Path $FileLoc"RevitServerToolCommand\"$DLL_09".dll" -Destination $FileLoc"RevitServerToolCommand\"$DLL_09".orig" -Force  
           Remove-Item -Path $FileLoc"RevitServerToolCommand\"$DLL_09".dll" -Force  
           Copy-Item -Path $Global:RelativePath"RevitServerToolCommand\"$DLL_09".dll" -Destination $FileLoc"RevitServerToolCommand\" -Force  
      }  
 }  
 Remove-Variable -Name DLL_01  
 Remove-Variable -Name DLL_02  
 Remove-Variable -Name DLL_03  
 Remove-Variable -Name DLL_04  
 Remove-Variable -Name DLL_05  
 Remove-Variable -Name DLL_06  
 Remove-Variable -Name DLL_07  
 Remove-Variable -Name DLL_08  
 Remove-Variable -Name DLL_09  
 Remove-Variable -Name FileLoc  
 Remove-Variable -Name OS  
 Remove-Variable -Name RelativePath  

PowerShell: Display all Add/Remove Program Entries with Uninstall String

Here is a script that will display all Add/Remove Program entries with the uninstall string, directly from the x86 and x64 registry keys.

You can download the script from here.

 #*******************************************************************************  
 #      Author: Mick Pletcher  
 #        Date: 12 June 2013  
 #  
 #     Program: Add/Remove Programs  
 # Description: This script will either list all applications in the Add/Remove  
 #              programs, which is pulled from both the registry. On a 64-bit  
 #              machine, it pulls from both the x86 and x64 add/remove programs  
 #              registry entries. You will also have the option to search for  
 #              a specific application.   
 #*******************************************************************************  
 cls

 $Global:OS  

 Function GetOSArchitecture{  
      $Global:OS=Get-WMIObject win32_operatingsystem  
      #$Global:OS.OSArchitecture  
      #Answers: 32-bit, 64-bit  
 }  

 $DisplayOutput = $false  
 GetOSArchitecture  
 [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")  
 [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null  
 $Output = [System.Windows.Forms.MessageBox]::Show("Search for a specific program?" , "Status" , 4)  
 If ($Output -eq "Yes"){  
      $ProgramName = [Microsoft.VisualBasic.Interaction]::InputBox("Enter specific software name:")  
      $ProgramName = "*"+$ProgramName+"*"  
 }  
 If ($Global:OS.OSArchitecture -eq "32-bit"){  
      $RegPath = "HKLM:\software\microsoft\windows\currentversion\uninstall\"  
      $Results = Get-ChildItem $RegPath -Recurse -ErrorAction SilentlyContinue  
      foreach ($item in $Resultsx86){  
           If (($item.GetValue("DisplayName") -ne $null) -and ($item.GetValue("UninstallString") -ne $null)) {  
                Write-Host  
                Write-Host  
             Write-Host "  Software: "$item.GetValue("DisplayName")  
                Write-Host "  Version: "$item.GetValue("DisplayVersion")  
             Write-Host "Uninstaller: "$item.GetValue("UninstallString")  
           }  
      }  
 }  
 If ($Global:OS.OSArchitecture -eq "64-bit"){  
      $RegPathx86 = "HKLM:\software\wow6432node\microsoft\windows\currentversion\uninstall\"  
      $RegPathx64 = "HKLM:\software\microsoft\windows\currentversion\uninstall\"  
      $Resultsx86 = Get-ChildItem $RegPathx86 -Recurse -ErrorAction SilentlyContinue  
      $Resultsx64 = Get-ChildItem $RegPathx64 -Recurse -ErrorAction SilentlyContinue  
      foreach ($item in $Resultsx86){  
           If (($item.GetValue("DisplayName") -ne $null) -and ($item.GetValue("UninstallString") -ne $null)) {  
                If ($Output -eq "Yes"){  
                     If ($item.GetValue("DisplayName") -like $ProgramName){  
                          $DisplayOutput = $true  
                     }  
                }else{  
                     $DisplayOutput = $true  
                }  
                If ($DisplayOutput -eq $true){  
                     Write-Host  
                     Write-Host  
                  Write-Host "  Software: "$item.GetValue("DisplayName")  
                     Write-Host "  Version: "$item.GetValue("DisplayVersion")  
                  Write-Host "Uninstaller: "$item.GetValue("UninstallString")  
                }  
           }  
           $DisplayOutput = $false  
      }  
      $DisplayOutput = $false  
      foreach ($item in $Resultsx64){  
           If (($item.GetValue("DisplayName") -ne $null) -and ($item.GetValue("UninstallString") -ne $null)) {  
                If ($Output -eq "Yes"){  
                     If ($item.GetValue("DisplayName") -like $ProgramName){  
                          $DisplayOutput = $true  
                     }  
                }else{  
                     $DisplayOutput = $true  
                }  
                If ($DisplayOutput -eq $true){  
                     Write-Host  
                     Write-Host  
                  Write-Host "  Software: "$item.GetValue("DisplayName")  
                     Write-Host "  Version: "$item.GetValue("DisplayVersion")  
                  Write-Host "Uninstaller: "$item.GetValue("UninstallString")  
                }  
           }  
           $DisplayOutput = $false  
      }  
 }  

11 June 2013

APPLYING WINDOWS UPDATE MSU FILES TO WIM IMAGES

This powershell script will inject all .msu files into a mounted WIM file. The script first scans the relative path of the directory that it was executed from for WIM files. Next, it mounts the WIM file. The script then scans the relative directory for all existing .msu files and writes them to an array. The msu files are then injected into the mounted WIM file. Once all updates are injected, the WIM is unmounted and cleaned up.

To use this, I suggest creating a separate directory and copying the script to it. Copy all of the pertinant .msu files and the WIM file over.

NOTE: Make sure to backup the WIM file before injecting the .msu files into it. Some updates are only online updates and will corrupt the WIM file if injected. You can read more on this topic in my blog located here.

You can download the script here.

 Clear-Host  
 $Global:MountPath  
 $Global:RelativePath  
 $Global:WimFile  
 $Global:UpdatesPath  
 Function GetRelativePath{  
      $Global:RelativePath=(split-path $SCRIPT:MyInvocation.MyCommand.Path -parent)+"\"  
      Write-Host $Global:RelativePath  
 }  
 Function GetWimFile{  
      $FileName = Get-ChildItem $Global:RelativePath | Where-Object {($_.Name -like "*.wim")}  
      $Global:WimFile = $Global:RelativePath+$FileName  
      Write-Host $Global:WimFile  
 }  
 Function MountWIM{  
      $Global:MountPath = $Global:RelativePath+"Mount\"  
      If ((Test-Path $Global:MountPath) -ne $true){  
           New-Item -ItemType directory -Path $Global:RelativePath"Mount"  
      }  
      Write-Host $Global:MountPath  
      $Arguments = "dism.exe /mount-wim /wimfile:"+$Global:WimFile+[char]32+"/index:1 /mountdir:"+$Global:MountPath  
      Write-Host $Arguments  
      Invoke-Expression -Command $Arguments  
 }  
 Function UnmountWIM{  
      $Arguments = "dism.exe /unmount-wim /mountdir:"+$Global:MountPath+[char]32+"/commit"  
      Write-Host $Arguments  
      Invoke-Expression -Command $Arguments  
 }  
 Function CleanupWIM{  
      $Arguments = "dism.exe /cleanup-wim"  
      Write-Host $Arguments  
      Invoke-Expression -Command $Arguments  
 }  
 Function GlobalMemoryCleanup{  
      Clear-Variable -Name MountPath -Scope Global -Force  
      Clear-Variable -Name WimFile -Scope Global -Force  
      Clear-Variable -Name UpdatesPath -Scope Global -Force  
      Clear-Variable -Name RelativePath -Scope Global -Force  
      Remove-Variable -Name MountPath -Scope Global -Force  
      Remove-Variable -Name WimFile -Scope Global -Force  
      Remove-Variable -Name UpdatesPath -Scope Global -Force  
      Remove-Variable -Name RelativePath -Scope Global -Force  
 }  
 GetRelativePath  
 GetWimFile  
 MountWIM  
 $Global:UpdatesPath = $Global:RelativePath+"*.msu"  
 $UpdatesArray = Get-Item $Global:UpdatesPath  
 ForEach ($Updates in $UpdatesArray) {  
      $Arguments = "dism.exe /image:"+$Global:MountPath+[char]32+"/Add-Package /PackagePath:"+$Updates  
      Write-Host $Arguments  
      Invoke-Expression -Command $Arguments  
      Start-Sleep -Seconds 10  
 }  
 UnmountWIM  
 CleanupWIM  
 Clear-Variable -Name Arguments -Scope Local -Force  
 Clear-Variable -Name Updates -Scope Local -Force  
 Clear-Variable -Name UpdatesArray -Scope Local -Force  
 Remove-Variable -Name Arguments -Scope Local -Force  
 Remove-Variable -Name Updates -Scope Local -Force  
 Remove-Variable -Name UpdatesArray -Scope Local -Force  
 GlobalMemoryCleanup  

26 May 2013

Porting NMEA Data to the iPhone and iPad

The first thing that has to be done is to make sure you have a device that can transmit NMEA data across WiFi, such as the Verizon MiFi 4620L. Next, you need to make sure the GPS over WiFi is enabled and is set to port 10110. Once this is set on the GPS over WiFi device, you now need an application that is capable of reading the NMEA data. In the application, you will need to enable NMEA and then configure the host and port. The host will be the default gateway, which is most likely 192.168.1.1. The port will be 10110. 

15 May 2013

Initiate Hardware Inventory

Here is the scripting code in both powershell and VBScript to initiate a hardware inventory in both SMS and SCCM. The backend calls are the same in both SMS and SCCM, so both scripts will work in either app.

Powershell
 Function InitiateHardwareInventory{  
      $SCCMClient = [wmiclass] "\\localhost\root\ccm:SMS_Client"  
      $SCCMClient.TriggerSchedule("{00000000-0000-0000-0000-000000000001}")  
 }  


VBScript
 Sub InitiateHardwareInventory()  
      On Error Resume Next  
      DIM oCPAppletMgr  : Set oCPAppletMgr  = CreateObject("CPApplet.CPAppletMgr")  
      DIM oClientAction : Set oClientAction = Nothing  
      DIM oClientActions : Set oClientActions = oCPAppletMgr.GetClientActions()  
      For Each oClientAction In oClientActions  
           If oClientAction.Name = "Hardware Inventory Collection Cycle" Then  
                oClientAction.PerformAction  
           End If  
      Next  
 End Sub