středa 27. dubna 2011

Nove procesy

Nove procesy v danem časovem oddobí

Get-Process | Where-Object { try { (New-Timespan $_.StartTime).TotalMinutes -le 5} catch { $false } }

sobota 2. dubna 2011

Powershell a HTML 5

V jednom postu byl zminěn koncept integrace powershellu a HTML5,našel jsem tam mimo jine toto  

                   iex (New-Object Net.WebClient).DownloadString("http://bit.ly/e0Mw9w")  

vložte do powershellu a budete překvapeni stejně jako já.

pondělí 7. března 2011

Powershell a Nmap

Dnes jsem při upravování výstupu pro netstat v powershellu  narazil v jine souvislosti na zajimavý ps1 script pro nmap.

http://blogs.sans.org/windows-security/2009/06/11/powershell-script-to-parse-nmap-xml-output/

Jeden z možných vystupů ktere exportuje potom vypadá takto

nmap2

neděle 27. února 2011

History script powershell

V ukázce bude nové vylepšené start-demo powershell,verze 3.3.3,hlavně ale viz niže, script pro praci s historii,vylepšený export,import atd.

Start-demo mimochodem podporuje vylepšenou automatizaci – autoexecute mode a autospeed parametr a mnoho mnoho dalšího.Je to předělavka původního Jeffrey Snover's original Start-Demo script od Joel "Jaykul" Bennetta.

Jak pracuje start demo a jak si tam vkladat svoje sekvence je popsáno jak na strankach poshcode kde je upravené start-demo ke stažení tak někde,bůhvíkde o hodně přispěvků zpět na tomto blogu.

Na konci videa je ještě ukazka prace s profilem powershellu– jeho uprava ,vlastní alias,vložení funkce,volání funkce.

Slibovaný script pro práci s historií,význam má alespon pro mne je to tak ,pokud je v profilu.Autora a popis si vyhledejte – bude bud na pashcode nebo technet scriptcentru,změnil jsem nazev funkce a maxcount,takže kdo chce původní hodnoty může se po něm mrknout,vzhledem k tomu že ho mam v profilu původní popis scriptu už nemám.Nicmeně vychazet by se mělo z http://www.nivot.org/2009/08/15/PowerShell20PersistingCommandHistory.aspx

#region History archiving           

function exporthistory {
param ([string]$path=$historyPath)
$cmdArray = @()
if (Test-Path $path) {
  $savedHistory = @(Import-Clixml $historyPath)           

        $savedHistory | % { $cmdArray += $_.CommandLine }           

  Get-History -Count $MaximumHistoryCount | % {
                #first level of filtering
                if ($cmdArray -notcontains $_.CommandLine) { $savedHistory += $_ }            

                #Second level of filtering to remove duplicates from current session also
                $cmdArray = @()
                $savedHistory | % { $cmdArray += $_.CommandLine }
                }           

  $savedHistory | Export-Clixml $path
  Write-Host -ForegroundColor Green "`nExported history to $path along with old import`n"
} else {
  Get-History -Count $MaximumHistoryCount | Export-Clixml $path
  Write-Host -ForegroundColor Green "`nExported history to $path`n"
}
}           

function Import-History {
param ([parameter(mandatory=$true)][string]$path=$historyPath)
if (Test-Path $(Split-Path $path)) {
  Import-Clixml $path | ? {$count++;$true} | Add-History
  Write-Host -Fore Green "`nLoaded $count history item(s) from $path`n"
}
}           

function Get-HistoryArchives {
$historyArchives = @()
$historyItems = Get-ChildItem $(Split-Path $profile) History*.clixml
$historyItems | % {
  $archive = New-Object PSObject
  $archive | Add-Member NoteProperty Name $_.Name
  $archive | Add-Member NoteProperty FullName $_.FullName
  $archive | Add-Member NoteProperty CreatedOn ($_.LastWriteTime).GetDateTimeFormats()[18]
  $historyArchives += $archive
}
$historyArchives
}           

function Show-HistoryArhive {
param ([parameter(mandatory=$true)][string]$path)
if (Test-Path $path) {
  Import-Clixml $path
}
}           

#reset $MaximumHistoryCount to 300
$MaximumHistoryCount = 300      

#Generate Histry export path for this session
$date = Get-Date
#This is not so good. But OK for now
$historyPath = "$((split-path $profile))\History$($date.Month)$($date.Day)$($date.Year).clixml"           

# This is from Nivot Ink's (@oising) blog post http://www.nivot.org/2009/08/15/PowerShell20PersistingCommandHistory.aspx
Register-EngineEvent -SourceIdentifier powershell.exiting -SupportEvent -Action { Export-History }           

# load the most recent history, if it exists
if ((Test-Path $(Split-Path $profile))) {
try {
     if (Test-Path $historyPath) {
   Import-History $historyPath
  } else {
    Write-Host -Fore Red "`nNo command history to restore`n"
   }
}
catch {
  Write-Host -Fore Red "`nNo command history to restore`n"
}
}
#endregion

function prompt {
  $mapped_drives =    Get-WmiObject Win32_LogicalDisk -Filter "drivetype=4" | foreach {echo $_.deviceid}
  $local_drives =     Get-WmiObject Win32_LogicalDisk -Filter "drivetype=3" | foreach {echo $_.deviceid}
  $removable_drives = Get-WmiObject Win32_LogicalDisk -Filter "drivetype=2" | foreach {echo $_.deviceid}
  $t = $(get-date -format "HH:mm:ss")
  $a = (get-location).path
  $d = (get-location).path.substring(0,$a.indexof(":")+1)
  $a = $a.substring($a.LastIndexOf("`\")+1)
  if ((get-location).path.substring(0,(get-location).path.indexof(":")) -eq "Microsoft.PowerShell.Core\FileSystem") {
    $a = (get-location).path
    $a = $a.substring($a.indexof(":")+2)
    write-host -fore white -back blue "$t - $a ";"`$`> "}
  else {
    if ($a -eq "") {$a = "`\"}
    if ($d.length -gt 2) {
      write-host -ForegroundColor black -backgroundcolor red "[$t] - [$d] $a ";"`$`> "}
    elseif ($local_drives -contains "$d") {
      write-host -ForegroundColor black -backgroundcolor green "[$t] - [$d] $a ";"`$`> "}
    elseif ($removable_drives -contains "$d") {
      write-host -ForegroundColor black -backgroundcolor yellow "[$t] - [$d] $a ";"`$`> "}
    elseif ($mapped_drives -contains "$d") {
      write-host -ForegroundColor black -backgroundcolor magenta "[$t] - [$d] $a ";"`$`> "}
  }
}

 

 

 

pátek 25. února 2011

Prompt - změna

function prompt {
  $mapped_drives =    Get-WmiObject Win32_LogicalDisk -Filter "drivetype=4" | foreach {echo $_.deviceid}
  $local_drives =     Get-WmiObject Win32_LogicalDisk -Filter "drivetype=3" | foreach {echo $_.deviceid}
  $removable_drives = Get-WmiObject Win32_LogicalDisk -Filter "drivetype=2" | foreach {echo $_.deviceid}
  $t = $(get-date -format "HH:mm:ss")
  $a = (get-location).path
  $d = (get-location).path.substring(0,$a.indexof(":")+1)
  $a = $a.substring($a.LastIndexOf("`\")+1)
  if ((get-location).path.substring(0,(get-location).path.indexof(":")) -eq "Microsoft.PowerShell.Core\FileSystem") {
    $a = (get-location).path
    $a = $a.substring($a.indexof(":")+2)
    write-host -fore white -back blue "$t - $a ";"`$`> "}
  else {
    if ($a -eq "") {$a = "`\"}
    if ($d.length -gt 2) {
      write-host -ForegroundColor black -backgroundcolor red "[$t] - [$d] $a ";"`$`> "}
    elseif ($local_drives -contains "$d") {
      write-host -ForegroundColor black -backgroundcolor green "[$t] - [$d] $a ";"`$`> "}
    elseif ($removable_drives -contains "$d") {
      write-host -ForegroundColor black -backgroundcolor yellow "[$t] - [$d] $a ";"`$`> "}
    elseif ($mapped_drives -contains "$d") {
      write-host -ForegroundColor black -backgroundcolor magenta "[$t] - [$d] $a ";"`$`> "}
  }
}

Tak tato změna  promptu se mně libí,dle popisu přidejete do profilu PS.

http://poshcode.org/2506

Replacment shell

čtvrtek 3. února 2011

Powershell modul pro advanced remote registry

http://code.msdn.microsoft.com/PSRemoteRegistry

reg

Smazani eventlogu

Zaloha vystupů z eventlogu,přidejte si připadně export kam je libo,jiným způsobem

Smazaní eventlogu – daný přiklad likviduje prostě vše,obrazek je pastnutý ale ze stroje který je prakticky co se týče zaznamů teměř netčený nějakýma vstupama  jediný zaznam tam byl jak vidíte pravě o předchozím mazaní – ID 1102.

Clear je tady celeho listu,můžete si nastavit pochopitelně jenom výběrové.

get-eventlog security | export-clixml -path Seclog.xml

Import-clixml Seclog.xml

get-eventlog -list |%{$_.clear()}

Ying Li

MyITforum.com

vymazeventlogu

středa 2. února 2011

Otevření www pomocí powershellu

Nahodou jsem viděl scripty na otevření www pomocí powershellu a všude se uvadělo že je nejjednodušší otevirat v IE.

Shay Levy http://blogs.microsoft.co.il/blogs/scriptfanatic/archive/tags/PowerShell/default.aspx ale uvádí mnohe elegantnější možnost a sice (New-Object -com Shell.Application).Open("http://www.microsoft.com")

úterý 1. února 2011

Powershell rozdilný výstup auditu

Další variantou jak najednou ziskat zakladní informace o PC a dal s nimi pracovat je vystup ogv.

Spuštění potom můžeme řešit přes ps1,execute in powershell a –NOEXIT,nebo přes dejme tomu vytvořeni funkce a spouštění scriptu nazvem funkce až ho chceme spustit,nebo cestou ke scriptu.Každopaádně admin mode bych preferoval.Na videu je varianta kdy udělame ps1 script obsahujici jenom přikazy a spouštime zadáním cesty k němu.

Varianta dvě zkopirujeme do okna powershellu nasledující

function audit
{Get-process|select-object *|ogv 
Get-WmiObject Win32_Process | ForEach-Object { $ownerraw = $_.GetOwner(); $owner = '{0}\{1}' -f $ownerraw.domain, $ownerraw.user;  $_ | Add-Member NoteProperty Owner $owner -PassThru } | Select-Object Name, Owner|ogv
Get-service|select-object *|ogv
Get-WmiObject Win32_Service | sort -property Name | select Name, State, ProcessId, Description, StartName |ogv
get-wmiobject Win32_QuickFixEngineering | sort -property HotFixID | select -property HotFixID, Description|ogv
get-wmiobject Win32_Desktop | sort -property Name | select Name, BorderWidth, Caption, CoolSwitch, CursorBlinkRate, Description, DragFullWindows, GridGranularity, IconSpacing, IconTitleFaceName, IconTitleSize, IconTitleWrap, Pattern, ScreenSaverActive, ScreenSaverExecutable, ScreenSaverSecure, ScreenSaverTimeout, SettingID, Wallpaper, WallpaperStretched, WallpaperTiled|ogv
get-wmiobject Win32_Environment | sort -property Name | select -property Name, Status, SystemVariable, UserName|ogv
get-wmiobject Win32_StartupCommand | sort -property Name | select -property Name, Location, Command|ogv
get-wmiobject Win32_BootConfiguration | select -property Name, BootDirectory, Description, LastDrive, ScratchDirectory, TempDirectory|ogv
get-wmiobject Win32_LogonSession | sort -property LogonId | select -property LogonId, LoginType, AuthenticationPackage, Description, InstallDate, StartTime|ogv
Get-EventLog -list|ogv
get-wmiobject Win32_ComputerSystem | select Name, Description, @{Label="DNS Host Name"; Expression={$_.DNSHostName}}, Domain, Manufacturer, Model, @{Label="# Processors";Expression={$_.NumberOfProcessors}}, @{Label="System Type";Expression={$_.SystemType}}, @{Label="Physical Memory";Expression={"{0,12:n0} MB" -f ($_.TotalPhysicalMemory/1mb)}}|ogv
get-wmiobject Win32_BIOS | select Name, Manufacturer, ReleaseDate, SerialNumber|ogv
get-wmiobject Win32_PhysicalMemory | select @{Label="Device Location";Expression={$_.DeviceLocator}}, DataWidth, @{Label="Capacity";Expression={"{0,12:n0} MB" -f ($_.Capacity/1mb)}}, PartNumber, SerialNumber, Speed|ogv
get-wmiobject Win32_IP4RouteTable | sort Destination | select Destination, Mask, NextHop, Age |ogv
get-wmiobject Win32_NetworkAdapterConfiguration | sort Description | select Description, DHCPEnabled, IPEnabled, ServiceName, SettingID|ogv
get-wmiobject Win32_NetworkAdapter | sort Name | select Name, Manufacturer, PhysicalAdapter, ServiceName, PNPDeviceID|ogv
get-wmiobject Win32_NetworkClient | select Name, Description, Manufacturer, Status|ogv
get-wmiobject Win32_NetworkLoginProfile -filter "NOT Name LIKE 'NT AUTHORITY%'" | sort Name | select Name, Comment, NumberOfLogons, LastLogon|ogv
get-wmiobject Win32_NetworkProtocol | sort Name | select Name, Description|ogv
get-wmiobject Win32_Printer | sort Name | select Name, Comment, DriverName, Location, Network, PortName, ShareName|ogv
get-wmiobject Win32_PrintJob | select Document, @{Label="Status";Expression={$_.JobStatus}}, Owner, @{Label="Pages";Expression={$_.TotalPages}}, @{Label="Submitted";Expression={[System.Management.ManagementDateTimeconverter]::ToDateTime($_.TimeSubmitted)}}|ogv
get-wmiobject Win32_PrinterDriver | sort Name | select Name, DriverPath|ogv
get-wmiobject Win32_DiskPartition | sort Name | select Name, @{Label="Size";Expression={"{0,12:n0} MB" -f ($_.Size/1mb)}}, @{Label="Primary?";Expression={$_.PrimaryPartition}}, @{Label="Boot?";Expression={$_.BootPartition}}|ogv
get-wmiobject Win32_LogicalDisk | select Name, Description, FileSystem, @{Label="Size";Expression={"{0,12:n0} MB" -f ($_.Size/1mb)}}, @{Label="Free Space";Expression={"{0,12:n0} MB" -f ($_.FreeSpace/1mb)}}, ProviderName|ogv
get-wmiobject Win32_MappedLogicalDisk | select Name, Description, FileSystem, @{Label="Size";Expression={"{0,12:n0} MB" -f ($_.Size/1mb)}}, @{Label="Free Space";Expression={"{0,12:n0} MB" -f ($_.FreeSpace/1mb)}}, ProviderName|ogv
get-wmiobject Win32_DiskDrive | sort Name | select Name, Model, MediaType, InterfaceType, Partitions, @{Label="Size";Expression={"{0,12:n0} MB" -f ($_.Size/1mb)}}|ogv
get-wmiobject Win32_Share | sort Name | select Name, Path, Status|ogv
Get-Content $env:windir\windowsupdate.log -encoding utf8 | Where-Object { $_ -like '*successfully installed*'} | Foreach-Object { $infos = $_.Split("`t"); $result = @{}; $result.Date = [DateTime]$infos[6].Remove($infos[6].LastIndexOf(":")); $result.Product = $infos[-1].SubString($infos[-1].LastIndexOf(":")+2);  New-Object PSobject -property $result  }|ogv
Get-Alias | Group-Object Definition|ogv

Odentrujeme a napišeme audit.

Video

Audit2

Další variantou je použit Powershell ISE,pro něj addon ISE MENU CREATOR a viz. obrazky niže.

Nedefinujeme si klavesovou zkratku a pouštime potom prostě klavesovou zkratkou.

psisemenu

psise1

pondělí 31. ledna 2011

Powershell existence kliče

Otestuj existenci daneho kliče  v registru a pokud neexistuje tak ho vytvoř.

if (Test-Path 'HKCU:\Software\testovaci') {
    "Registry key HKCU:\Software\testovaci already exists."
} else {
    md HKCU:\Software\testovaci}

powershellreg

čtvrtek 27. ledna 2011

Powershell Analyzer

Po marných pokusech se sžít s Poweshell ISE jsem nakonec jako druhý editor po vynikajicím powergui zvolil asi definitivně Powershell Analyzer.

http://www.powershellanalyzer.com/   Domovská stranka 

Je zvlaštní že Powershell ISE přitom není vůbec špatný,s addonem ISE MENU CREATOR je genialní,možnost tabů,remote tabů,co ma tak to prostě funguje bez problémů  ale prostě se mně v něm špatně orientuje asi by to chtělo někoho kdo by se zamyslel nad jeho gui.Nebo mně prostě nesedlo.

Powershell ISE

středa 26. ledna 2011

Eventlog 1hours

Dvakrat enter ,vystup ogv a v něm filtrovaní požadavků.

Tip powershell.com

$from = (Get-Date) - (New-Timespan -hour 1)

get-eventlog -List |
    Select-Object -ExpandProperty Log |
    Foreach-Object { Write-Progress 'Examining Eventlog' $_; $_} |
    Foreach-Object {$log = $_; 
    try { Get-EventLog -after $from -LogName $log -ea stop |
    Add-Member NoteProperty EventLog $log -pass  }
    catch { Write-Warning "Unable to access $log : $_"} } |
    Sort-Object TimeGenerated -desc  |
    Select-Object EventLog, TimeGenerated, EntryType, Source, Message | ogv

 

úterý 25. ledna 2011

Get-eventlog

Get-Eventlog "System" |
Where-Object {$_.EntryType -eq "Warning"} |
Where-Object {($_.TimeWritten).Date -eq (Get-Date).today}| ConvertTo-HTML |out-file D:\dreport.html

get-eventlog system -after (get-date).AddHours(-48) -EntryType Error,Warning | ConvertTo-HTML |out-file D:\warningreport.html

get-eventlog security -After (get-date).AddHours(-24) | ConvertTo-HTML |out-file D:\eventsecurity.html

úterý 11. ledna 2011

Powershell–vypis změn v umistnění

Script který nám vypiše změny ktere proběhly v umistnění ktere nas zajimá.Přikaz spustime v cilovem umistnění – script si upravime na časove období ktere nas zajímá.

$DateToCompare = (Get-date).AddDays(-6)

Get-Childitem –recurse | where-object {$_.lastwritetime –gt $DateToCompare}

Výpis potom vypadá nějak takto

Powershellcompare

úterý 28. prosince 2010

Powershell a Chromium

Dnešni script ukaže jak si stahnout vždy poslední verzi chromia – vývojová větev dev kanal.Zaroven uvidíme v akci modul bitstransfer.Na videu je volba chromium a miniinstaler.

 

Set-StrictMode -Version Latest
Import-Module bitstransfer

# comment out when not debugging
$VerbosePreference = "Continue"
#$VerbosePreference = "SilentlyContinue"

$versionFile = "$Env:temp\latestChromiumVersion.txt"
$installedChromiumVersion = 0

trap [Exception] {
      write-host
      write-error $("TRAPPED: " + $_.Exception.GetType().FullName);
      write-error $("TRAPPED: " + $_.Exception.Message);
      [string]($installedChromiumVersion) > $versionFile
      exit;
}


if (Test-Path $versionFile)
{ $installedChromiumVersion = [int32] (cat $versionFile) }

$latestChromiumBuildURL ="http://build.chromium.org/f/chromium/snapshots/chromium-rel-xp"
Start-BitsTransfer "$latestChromiumBuildURL/LATEST" $versionFile
$latestChromiumVersion = [int32] (cat $versionFile)

if ($installedChromiumVersion -eq $latestChromiumVersion)
{
    Write-Verbose "Exiting... Version $installedChromiumVersion is the latest."
    return
}

$installerAppName = "mini_installer"
$installer = "$Env:temp\$installerAppName.exe"
Write-Verbose "Initiating download of new version $latestChromiumVersion"
Start-BitsTransfer "$latestChromiumBuildURL/$latestChromiumVersion/mini_installer.exe" $installer
Write-Verbose "Installing new version of Chromium"
Invoke-Item $installer
$installerRunning = 1
while (!($installerRunning -eq $null))
{
    sleep 5
    $installerRunning = ( Get-Process | ? {$_.ProcessName -match "$installerAppName"} )
}

Write-Verbose "New Chromium Installed! Please restart the Chromium browser"

Powershell a chromium

neděle 26. prosince 2010

Powershell patchimage windowsupdate

Video je kratka ukazka toho jak updatovat  vhd image automaticky powershell scriptem.Platí a to hlavně to platí i pro wim….Jinak další zajímavý script powershellu řeší i známý problem diskpart a jeho nekorektní chování a vhd ale o něm někdy přiště

Osobně VHD mam ve virtualu,jako multiboot a v několika verzich jak plynul čas a k nejrůznějšímu použití.

Funkce má nespočet využití – některe si prostě přečtete  ve scriptu,jiné na strankach autora scriptu,no a další a další můžete přidávat podle toho k čemu vhd nebo wim použivate – nepouživate.

Stránky autora scriptu s podrobným popisem

http://www.optimalizovane-it.cz/windows-7/imagepatcher-aktualizujte-wim-a-vhd-z-windows-update.html

Video


patchimage


čtvrtek 23. prosince 2010

PowerShell vánoční pozdrav Get-Tree

 

#.Synopsis
#  Creates a fir tree in your console!
#.Description
#  A simple christmas tree simulation with (optional) flashing lights.
#  Requires your font be set to a True Type font (best results with Consolas).
#.Parameter Trim
#  Whether or not to trim the tree. NOTE: In violation of convention, this switch to true!
#  To disable the tree lights, use Get-Tree -Trim:$false
#.Example
#  Get-Tree -Trim:$false
#.Example
#  Get-tree Red, Cyan, Blue, Gray, Green
#
#  Description
#  -----------
#  Creates a tree with multi-colored lights in the five colors that work best...
param(
   [switch]$Trim=$true
,
   [ValidateSet("Red","Blue","Cyan","Yellow","Green","Gray","Magenta","All")]
   [Parameter(Position=0)]
   [String[]]$LightColor = @("Red")
)
if($LightColor -contains "All") {
   $LightColor = "Red","Yellow","Green","Gray","Magenta","Cyan","Blue"
}

Clear-Host
$OFS = "`n"
$center = [Math]::Min( $Host.UI.RawUI.WindowSize.Width, $Host.UI.RawUI.WindowSize.Height ) - 10

$Sparkle = [string][char]0x0489 
$DkShade = [string][char]0x2593
$Needles  = [string][char]0x0416

$Width = 2
[string[]]$Tree = $(
   "$(" " * $Center) "
   "$(" " * $Center)$([char]0x039B)"
   "$(" " * ($Center - 1))$($Needles * 3)"
 
   for($i = 3; $i -lt $center; $i++) {
      (" " * ($Center - $i)) + (Get-Random $Needles, " ") + ($Needles * (($Width * 2) + 1)) + (Get-Random $Needles, " ")
      $Width++
   }
   for($i = 0; $i -lt 4; $i++) {
      " " * ($Center + 2)
   }
)

$TreeOn = $Host.UI.RawUI.NewBufferCellArray( $Tree, "DarkGreen", "DarkMagenta" )
$TreeOff = $Host.UI.RawUI.NewBufferCellArray( $Tree, "DarkGreen", "DarkMagenta" )

# Make the tree trunk black
for($x=-2;$x -le 2;$x++) {
   for($y=0;$y -lt 4;$y++) {
      $TreeOn[($center+$y),($center+$x)] = $TreeOff[($center+$y),($center+$x)] =
         New-Object System.Management.Automation.Host.BufferCell $DkShade, "Black", "darkMagenta", "Complete"
   } 
}

if($trim) {
$ChanceOfLight = 50
$LightIndex = 0
for($y=0;$y -le $TreeOn.GetUpperBound(0);$y++) {
   for($x=0;$x -le $TreeOn.GetUpperBound(1);$x++) {
      # only put lights on the tree ...
      if($TreeOn[$y,$x].Character -eq $Needles) {
         $LightIndex += 1
         if($LightIndex -ge $LightColor.Count) {
            $LightIndex = 0
         }
         # distribute the lights randomly, but not next to each other
         if($ChanceOfLight -gt (Get-Random -Max 100)) {
            # Red for on and DarkRed for off.
            $Light = $LightColor[$LightIndex]
            $TreeOn[$y,$x] = New-Object System.Management.Automation.Host.BufferCell $Sparkle, $Light, "darkMagenta", "Complete"
            $TreeOff[$y,$x] = New-Object System.Management.Automation.Host.BufferCell $Sparkle, "Dark$Light", "darkMagenta", "Complete"
            $ChanceOfLight = 0 # Make sure the next spot won't have a light
         } else {
            # Increase the chance of a light every time we don't have one
            $ChanceOfLight += 3
         }
      }
   }
}
# Set the star on top
$TreeOn[0,$Center] = $TreeOff[0,$Center] = New-Object System.Management.Automation.Host.BufferCell $Sparkle, "Yellow", "darkMagenta", "Complete"
}


# Figure out where to put the tree
$Coord = New-Object System.Management.Automation.Host.Coordinates (($Host.UI.RawUI.WindowSize.Width - ($Center*2))/2), 2
$Host.UI.RawUI.SetBufferContents( $Coord, $TreeOff )

while($trim) { # flash the lights on and off once per second, if we trimmed the tree
   sleep -milli 500
   $Host.UI.RawUI.SetBufferContents( $Coord, $TreeOn )
   sleep -milli 500
   $Host.UI.RawUI.SetBufferContents( $Coord, $TreeOff )
}