Advertisement
JL421

Font Install Script

Jan 9th, 2014
248
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.     <#
  2.     .SYNOPSIS
  3.         Installs fonts to the local machine when run.
  4.     .Description
  5.         Installs all fonts in a folder to the local system. This script is intended to be run by group policy to install fonts on system startup.
  6.         After startup this script behaves like a service, and checks for new additions or deletions from the remote lists every 30 minutes and acts
  7.  
  8. accordingly.
  9.     .NOTES
  10.         File Name   : font_install.ps1
  11.         Author      : JL421
  12. #>
  13.  
  14.     #====================#
  15.     #Load Required Assemblies#
  16.     #====================#
  17.    
  18.     #This Assembly allows for faster and less resource intensive file name retrieval.#
  19.     [reflection.assembly]::loadwithpartialname("Microsoft.VisualBasic") | Out-Null
  20.    
  21.    
  22.     #====================#
  23.     #Set Initial Variables#
  24.     #====================#
  25.    
  26.     #Numeric Representation of %WinDir%\Fonts#
  27.     $FONTS = 0x14
  28.    
  29.     #Creating the Shell object to copy and install fonts.#
  30.     $objShell = New-Object -ComObject Shell.Application
  31.     $objFolder = $objShell.Namespace($FONTS)
  32.    
  33.    
  34.     $LocalFontDir = "C:\Windows\Fonts\"
  35.     $LocalFontDirRegex = "C:\\Windows\\Fonts\\"
  36.    
  37.     #Sets the Division Code to the First Argument in script call if it was entered. If not it gets the division code from the first 3 characters of the Computer Name.#
  38.     $Division = IF ($args[1] -ne $null)
  39.     {
  40.         $args[1]
  41.     }
  42.     ELSE
  43.     {
  44.         $env:COMPUTERNAME.Substring(0,3)
  45.     }
  46.    
  47.     #Sets the Department Code to the Second Argument in script call if it was entered. If not it get the department code from the 4th through 7th characters of the Computer Name.#
  48.     $Department = IF ($args[2] -ne $null)
  49.     {
  50.         $args[2]
  51.     }
  52.     ELSE
  53.     {
  54.         $env:COMPUTERNAME.Substring(3,4)
  55.     }
  56.    
  57.     #Sets the local font location and the location with the \ Regex'ed out.#
  58.     $LocalFontDir = "C:\Windows\Fonts\"
  59.     $LocalFontDirRegex = "C:\\Windows\\Fonts\\"
  60.    
  61.     $BaseFontDir = "\\server\basefontfolder\"
  62.    
  63.     $BaseFontDirRegex =
  64.         "\\\\server\\basefontfolder\\"
  65.    
  66.     #Sets the Division and Department Directories and Regexes based on the provided Division and Department Codes.#
  67.     IF ($Division -eq "D01")
  68.     {
  69.         $DivisionFontDir = $BaseFontDir + "\division1folder"
  70.         $DivisionFontDirRegex = $BaseFontDirRegex + "division1folder\\"
  71.     }
  72.     ELSEIF ($Division -eq "D02")
  73.     {
  74.         $DivisionFontDir = $BaseFontDir + "\division2folder"
  75.         $DivisionFontDirRegex = $BaseFontDirRegex + "division2folder\\"
  76.        
  77.     }
  78.     IF ($Department -like "AD*" -or $Department -like "ADV*")
  79.     {
  80.         $DepartmentFontDir = $DivisionFontDir + "\Advertising"
  81.         $DepartmentFontDirRegex = $DivisionFontDirRegex + "Advertising\\"
  82.     }
  83.     ELSEIF ($Department -like "CS*")
  84.     {
  85.         $DepartmentFontDir = $DivisionFontDir + "\CreativeServices"
  86.         $DepartmentFontDirRegex = $DivisionFontDirRegex + "CreativeServices\\"
  87.     }
  88.    
  89.     #Sets the Exclusion Font and Regex lists. (Fonts that may be installed on a specific machine that should not be removed.)#
  90.     $ExclusionFontDir = $DepartmentFontDir + "\Exclusions"
  91.     $ExclusionFontDirRegex = $DepartmentFontDirRegex + "Exclusions\\"
  92.    
  93.    
  94.     #====================#
  95.     #Define Script Functions#
  96.     #====================#
  97.    
  98.     #Gets the registry name of a font based on the font file name.#
  99.     function Get-RegistryStringNameFromValue([string] $keyPath, [string] $valueData)
  100.     {
  101.         $pattern = [Regex]::Escape($valueData)
  102.         foreach($property in (Get-ItemProperty $keyPath).PsObject.Properties)
  103.         {
  104.             #Skip the property if it was one PowerShell added
  105.             if(($property.Name -eq "PSPath") -or
  106.                 ($property.Name -eq "PSChildName"))
  107.             {
  108.                 continue
  109.             }
  110.             #Search the text of the property
  111.             $propertyText = "$($property.Value)"
  112.             if($propertyText -match $pattern)
  113.             {
  114.                 "$($property.Name)"
  115.             }
  116.         }
  117.     }
  118.    
  119.     #Adds or Deletes fonts from the system based on arguments presented.#
  120.     #First Argument Function: Font List being input into function.#
  121.     #Second Argument Functions: Calls add or delete function - 0 = Delete, 1 = Add.#
  122.     #Third Argument Functions: Tells the function if the input list is the Base (0), Division (1), or Department (2) font list.
  123.     function FontAddDelete
  124.     {
  125.         IF ($args[1] -eq 1)
  126.         {
  127.             ForEach ($i in $args[0])
  128.             {
  129.                 IF ($args[2] -eq 0)
  130.                 {
  131.                     $FontLocation = $BaseFontDir + "\" + $i
  132.                     $objFolder.CopyHere($FontLocation)
  133.                 }
  134.                 ELSEIF ($args[2] -eq 1)
  135.                 {
  136.                     $FontLocation = $DivisionFontDir + "\" + $i
  137.                     $objFolder.CopyHere($FontLocation)
  138.                 }
  139.                 ELSEIF ($args[2] -eq 2)
  140.                 {
  141.                     $FontLocation = $DepartmentFontDir + "\" + $i
  142.                     $objFolder.CopyHere($FontLocation)
  143.                 }
  144.             }
  145.         }
  146.         ELSEIF ($args[1] -eq 0)
  147.         {
  148.             ForEach ($i in $args[0])
  149.             {
  150.                 IF ($i.Substring($i.Length - 4) -eq ".pfm")
  151.                 {
  152.                     $RegistryKey = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Type 1 Installer\Type 1 Fonts"
  153.                     $KeyName = Get-RegistryStringNameFromValue $RegistryKey $i
  154.                     Remove-ItemProperty -Path $RegistryKey -Name $KeyName
  155.                     $FontPFM = $LocalFontDir + "\" + $i
  156.                     $FontPFB = $LocalFontDir + "\" + $i.Substring(0,$i.Length - 4) + ".pfb"
  157.                     Remove-Item $FontPFM
  158.                     Remove-Item $FontPFB
  159.                 }
  160.                 ELSEIF ($i.Substring($i.Length -4) -eq ".fon" -or $i.Substring($i.Length -4) -eq ".otf" -or $i.Substring($i.Length -4) -eq ".ttc" -or $i.Substring($i.Length -4) -eq ".ttf")
  161.                 {
  162.                     $RegistryKey = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts"
  163.                     $KeyName = Get-RegistryStringNameFromValue $RegistryKey $i
  164.                     Remove-ItemProperty -Path $RegistryKey -Name $KeyName
  165.                     $FontLocation = $LocalFontDir + "\" + $i
  166.                     Remove-Item $FontLocation
  167.                 }
  168.             }
  169.         }
  170.     }
  171.    
  172.     Function Process
  173.     {
  174.         #Gets the list of font files with the extensions: .pfm (Type 1 Font - Bitstream), .fon (Font Files), .otf (OpenTypeFonts), .ttc (TrueType Collections), .ttf (TrueType Fonts).#
  175.         #It also removes the path from the file name to only return the file name.#
  176.         $LocalFontList = [Microsoft.VisualBasic.FileIO.FileSystem]::GetFiles($LocalFontDir) | ForEach {$_ -replace $LocalFontDirRegex, ""} | Where {$_.Substring($_.Length -4) -eq ".pfm" -or $_.Substring($_.Length -4) -eq ".fon" -or $_.Substring($_.Length -4) -eq ".otf" -or $_.Substring($_.Length -4) -eq ".ttc" -or $_.Substring($_.Length -4) -eq ".ttf"}
  177.         $BaseFontList = [Microsoft.VisualBasic.FileIO.FileSystem]::GetFiles($BaseFontDir) | ForEach {$_ -replace $BaseFontDirRegex, ""} | Where {$_.Substring($_.Length -4) -eq ".pfm" -or $_.Substring($_.Length -4) -eq ".fon" -or $_.Substring($_.Length -4) -eq ".otf" -or $_.Substring($_.Length -4) -eq ".ttc" -or $_.Substring($_.Length -4) -eq ".ttf"}
  178.         $DivisionFontList = [Microsoft.VisualBasic.FileIO.FileSystem]::GetFiles($DivisionFontDir) | ForEach {$_ -replace $DivisionFontDirRegex, ""} | Where {$_.Substring($_.Length -4) -eq ".pfm" -or $_.Substring($_.Length -4) -eq ".fon" -or $_.Substring($_.Length -4) -eq ".otf" -or $_.Substring($_.Length -4) -eq ".ttc"  -or $_.Substring($_.Length -4) -eq ".ttf"}
  179.         $DepartmentFontList = [Microsoft.VisualBasic.FileIO.FileSystem]::GetFiles($DepartmentFontDir) | ForEach {$_ -replace $DepartmentFontDirRegex, ""} | Where {$_.Substring($_.Length -4) -eq ".pfm" -or $_.Substring($_.Length -4) -eq ".fon" -or $_.Substring($_.Length -4) -eq ".otf" -or $_.Substring($_.Length -4) -eq ".ttc" -or $_.Substring($_.Length -4) -eq ".ttf"}
  180.         $ExclusionFontList = [Microsoft.VisualBasic.FileIO.FileSystem]::GetFiles($ExclusionFontDir) | ForEach {$_ -replace $ExclusionFontDirRegex, ""} | Where {$_.Substring($_.Length -4) -eq ".pfm" -or $_.Substring($_.Length -4) -eq ".fon" -or $_.Substring($_.Length -4) -eq ".otf" -or $_.Substring($_.Length -4) -eq ".ttc" -or $_.Substring($_.Length -4) -eq ".ttf"}
  181.        
  182.         #Creates a list of all fonts to decide what needs to be deleted. This list includes the Exclusion list in order to exclude it from deletion.#
  183.         $AllFontList = $BaseFontList + $DivisionFontList + $DepartmentFontList | Sort
  184.        
  185.         #Creates a list of local fonts with the underscore characters removed. Windows will tourniquet underscores at random length if multiple appear in a font file name.#
  186.         #This allows us to keep fonts with underscores in the name without replacing them each time the script is run.#
  187.         $LocalFontListNoUS = $LocalFontList | ForEach {$_ -replace "_", ""}
  188.    
  189.         IF ($LocalFontListNoUS -ne $null)
  190.         {
  191.             IF ($AllFontList -ne $null)
  192.             {
  193.                 #Creates an AllFontList without underscores to match against the local list.#
  194.                 $AllFontListNoUS = $AllFontList | ForEach {$_ -replace "_", ""}
  195.            
  196.                 #If the Compare shows the font is local, but not in either the Base, Division, Department, or Exclusion Lists it marks the font for Deletion.#
  197.                 $FontDeleteListNoUS = Compare-Object $AllFontListNoUS $LocalFontListNoUS | Where-Object {$_.SideIndicator -eq "=>"} | Select-Object -ExpandProperty InputObject
  198.    
  199.                 IF ($FontDeleteListNoUS -ne $null)
  200.                 {
  201.                     #Defines a blank array for the Font Delete List so the next function can add items to it.#
  202.                     $FontDeleteList = @()
  203.    
  204.                     ForEach ($i in $FontDeleteListNoUS)
  205.                     {
  206.                         $FontLike = $i.Substring(0,$i.Length -4) + "*"
  207.                         $Font = $LocalFontList -like $FontLike
  208.                        
  209.                         #Sets the Reboot Bit if there is a match.#
  210.                         IF ($Font -ne $null)
  211.                         {
  212.                             $RebootNeeded = 1
  213.                         }
  214.    
  215.                         $FontDeleteList = $FontDeleteList + $Font
  216.                     }
  217.                     IF ($FontDeleteList -ne $null)
  218.                     {
  219.                         FontAddDelete $FontDeleteList 0
  220.                     }
  221.                 }
  222.             }
  223.         }
  224.    
  225.         IF ($BaseFontList -ne $null)
  226.         {
  227.             #Creates a BaseFontList without underscores to match against the local list.#
  228.             $BaseFontListNoUS = $BaseFontList | ForEach {$_ -replace "_", ""}
  229.    
  230.             IF ($LocalFontList -eq $null) #If the Local Font List is empty, add all fonts in the Base font list. (This should never happen!)#
  231.             {
  232.                 FontAddDelete $BaseFontList 1 0
  233.             }
  234.             Else
  235.             {
  236.                 #If the Compare shows the font is in the Base list, but not on the local list, it marks it for Installation.#
  237.                 $BaseFontAddNoUS = Compare-Object $BaseFontListNoUS $LocalFontListNoUS | Where-Object {$_.SideIndicator -eq "<="} | Select-Object -ExpandProperty InputObject
  238.    
  239.                 IF ($BaseFontAddNoUS -ne $null)
  240.                 {
  241.                     #Defines a blank array for the Base Font Add list so the next function can add items to it.#
  242.                     $BaseFontAdd = @()
  243.    
  244.                     ForEach ($i in $BaseFontAddNoUS)
  245.                     {
  246.                         $FontLike = $i.Substring(0,$i.Length -4) + "*"
  247.                         $Font = $BaseFontList -like $FontLike
  248.                        
  249.                         #Sets the Reboot Bit if there is a match.#
  250.                         IF ($Font -ne $null)
  251.                         {
  252.                             $RebootNeeded = 1
  253.                         }
  254.    
  255.                        
  256.                         $BaseFontAdd = $BaseFontAdd + $Font
  257.                     }
  258.    
  259.                     IF ($BaseFontAdd -ne $null)
  260.                     {
  261.                         FontAddDelete $BaseFontAdd 1 0
  262.                     }
  263.                 }
  264.             }
  265.         }
  266.    
  267.         IF ($DivisionFontList -ne $null)
  268.         {
  269.             #Creates a DivisionFontList without underscores to match against the local list.#
  270.             $DivisionFontListNoUS = $DivisionFontList | ForEach {$_ -replace "_", ""}
  271.    
  272.             IF ($LocalFontList -eq $null) #If the Local Font List is empty, add all fonts in the Division font list. (This should never happen!)#
  273.             {
  274.                 FontAddDelete $DivisionFontList 1 1
  275.             }
  276.             Else
  277.             {
  278.                 #If the Compare shows the font is in the Division list, but not on the local list, it marks it for Installation.#
  279.                 $DivisionFontAddNoUS = Compare-Object $DivisionFontListNoUS $LocalFontListNoUS | Where-Object {$_.SideIndicator -eq "<="} | Select-Object -ExpandProperty InputObject
  280.    
  281.                 IF ($DivisionFontAddNoUS -ne $null)
  282.                 {
  283.                     #Defines a blank array for the Division Font Add list so the next function can add items to it.#
  284.                     $DivisionFontAdd = @()
  285.    
  286.                     ForEach ($i in $DivisionFontAddNoUS)
  287.                     {
  288.                         $FontLike = $i.Substring(0,$i.Length -4) + "*"
  289.                         $Font = $DivisionFontList -like $FontLike
  290.                        
  291.                         #Sets the Reboot Bit if there is a match.#
  292.                         IF ($Font -ne $null)
  293.                         {
  294.                             $RebootNeeded = 1
  295.                         }
  296.    
  297.                        
  298.                         $DivisionFontAdd = $DivisionFontAdd + $Font
  299.                     }
  300.    
  301.                     IF ($DivisionFontAdd -ne $null)
  302.                     {
  303.                         FontAddDelete $DivisionFontAdd 1 1
  304.                     }
  305.                 }
  306.             }
  307.         }
  308.    
  309.         IF ($DepartmentFontList -ne $null)
  310.         {
  311.             #Creates a DepartmentFontList without underscores to match against the local list.#
  312.             $DepartmentFontListNoUS = $DepartmentFontList | ForEach {$_ -replace "_", ""}
  313.    
  314.             IF ($LocalFontList -eq $null) #If the Local Font List is empty, add all fonts in the Department font list. (This should never happen!)#
  315.             {
  316.                 FontAddDelete $DepartmentFontList 1 2
  317.             }
  318.             Else
  319.             {
  320.                 #If the Compare shows the font is in the Department list, but not on the local list, it marks it for Installation.#
  321.                 $DepartmentFontAddNoUS = Compare-Object $DepartmentFontListNoUS $LocalFontListNoUS | Where-Object {$_.SideIndicator -eq "<="} | Select-Object -ExpandProperty InputObject
  322.    
  323.                 IF ($DepartmentFontAddNoUS -ne $null)
  324.                 {
  325.                     #Defines a blank array for the Department Font Add list so the next function can add items to it.#
  326.                     $DepartmentFontAdd = @()
  327.    
  328.                     ForEach ($i in $DepartmentFontAddNoUS)
  329.                     {
  330.                         $FontLike = $i.Substring(0,$i.Length -4) + "*"
  331.                         $Font = $DepartmentFontList -like $FontLike
  332.                        
  333.                         #Sets the Reboot Bit if there is a match.#
  334.                         IF ($Font -ne $null)
  335.                         {
  336.                             $RebootNeeded = 1
  337.                         }
  338.    
  339.                        
  340.                         $DepartmentFontAdd = $DepartmentFontAdd + $Font
  341.                     }
  342.    
  343.                     IF ($DepartmentFontAdd -ne $null)
  344.                     {
  345.                         FontAddDelete $DepartmentFontAdd 1 2
  346.                     }
  347.                 }
  348.             }
  349.         }
  350.         IF ($RebootNeeded -eq 1)
  351.         {
  352.             #If the reboot bit is set, the system will notify the user that they have 5 minutes to save their work and reboot on their own, or the system will reboot automatically.#
  353.             #This allows any changes made to be applied.#
  354.             Shutdown /r /t 300 /f /c "Your Computer needs to be rebooted to finish installing or removing Fonts. Please save your work and restart your computer now. Your computer will automatically restart in 5 minutes."
  355.         }
  356.     }
  357.    
  358.     #====================#
  359.     #Running Script#
  360.     #====================#
  361.    
  362.     IF ($args[0] -eq 1)
  363.     {
  364.         Do
  365.         {
  366.             Process
  367.             Start-Sleep 1800
  368.         }
  369.         While ($null -eq $null)
  370.     }
  371.     ELSE
  372.     {
  373.         Process
  374.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement