Powershell脚本添加大量网络打印机

时间:2016-12-07 18:52:06

标签: powershell printing network-printers

我工作的打印机不断变化。因此,我需要一个脚本,可以自动完成添加和删除打印机的过程,几乎没有干预。我在这里有一个我用来执行此任务的代码示例。我想简化这段代码并添加2个新功能,不幸的是,我的编码能力很少,因为我只是一个不起眼的系统管理员。

新功能理念:

  1. 如果.vbs文件'上次修改'自上次运行此脚本以来,日期未被更改,脚本立即停止。概述一种覆盖这种方法的评论也会很好。

  2. 显示创建了哪些服务器的日志文件,我想知道它们是否已创建 - 成功 - 或者是否失败。

  3. 如果脚本在添加网络打印机时遇到错误,它会立即跳过它,但日志会显示已添加创建的打印机

        <#
        .SYNOPSIS
         Printer Script
         1. Archives the working file if it is greater than or equal to 1 MB
         2. Starts logging
         3. Removes priners which no longer exist on the print server (because of deletion, moves, etc) in a status of 2
         4. Compares the Network printer list to the locally installed Network printers and outputs a list of the printers not installed locally
         5. Takes the new printer list, and pings each printer, if ping fails, the printer is removed from the install list
         6. Builds new printers
         7. Ends logging
         8. Performs log file maintenance by archiving and removing old log files
    
    
        .DESCRIPTION
        Date: 04/03/2013
        Version: 1
        PowerShell Version: 2.0
    
        .INPUTS
        Network Printer Script \\ShareDrive\Sharefolder\ShareFile.vbs
    
        .OUTPUTS
        Log files
        Archive files
        Temp text files 
           ShareFile.txt
           pl.txt
           Localprinters.txt
           NewPrinters.txt
           ToDelete.txt
           working.txt
    
        .EXAMPLE
        C:\scripts\PrinterMaint.ps1
    
        .NOTES
        Create the following folders before running this script:
        C:\PrinterMaint\
        C:\temp\
        C:\Scripts\
    
        .LINK
    
    
        #>
    
    ###################
    ####-VARIABLES-####
    ###################
    
        # Get computer name
        $Server = (gc env:computername)
    
        # Specifies Local Printer Properties to be retrieved
        $Props = "Name","PrinterStatus"
    
        $GLOBAL:job1 = ""
    
        # Log file naming convention
        $Logfile = "C:\PrinterMaint\"+$(gc env:computername)+".log"
    
        # Archive log naming convention
        $archive = "C:\PrinterMaint\Archive_"+(gc env:computername)+"_"+$date2+".log"
    
        # Gets todays date and assigns it to a variable
        $date = Get-Date
    
        # temp files and path of text file which holds the names of the printers to be deleted
        $DelFile = "C:\temp\ToDelete.txt"
    
        # Creates a formatted date which can be used in a file name
        $date2 = Get-Date -format "yyyy-MM-ddTHHmmss"
    
        # Error File
        $ErrorFile = "C:\PrinterMaint\Errors.log"
    
        # Handle Errors
        $ErrorActionPreference = "silentlycontinue"
    
        # Get computer name
         $Server = (gc env:computername)
    
        # Local Printer
         $GOBAL:LPrinter = @()
    
         $GLOBAL:ltext = @()
    
         $GLOBAL:FinalPrinters = @()
    
         $GLOBAL:Bad = @()
    
    
    ###################
    ####-FUNCTIONS-####
    ###################
    
        Function ServiceShutdown #Shuts down High CPU services while this script runs so as to not interfere
        {
            Set-Service SAVAdminService -StartupType Disabled
            Stop-Service SAVAdminService
            Set-Service SavService -StartupType Disabled
            Stop-Service SavService
        }
    
         Function CycleSpooler
        {
            Write-Host "Cycling Print Spooler"
            Stop-Service spooler
            Start-Sleep -seconds 10
            Start-Service spooler
            Write-Host "Print Spooler Cycle is complete"
        }
    
         Function ServiceReenable
        {
            Set-Service SavService -StartupType Automatic
            Start-Service SavService
            Set-Service SAVAdminService -StartupType Automatic
            Start-Service SAVAdminService
        }
    
        Function GetLocalPrinters
        {
            # Start gathering local printer info
            $GLOBAL:job1 = gWmi Win32_Printer -computer $Server -Property $props -AsJob
    
            If ($GLOBAL:job1.State -eq "Running")
            {
                Cls
                Write-Host "The local Printer gather may take several minutes to complete" -ForegroundColor Blue -BackgroundColor Yellow
                $i = 0
    
                do {Write-Progress -Activity "Gathering Local Printers..." -status "$i seconds";$i+=5; Start-sleep -seconds 5}
                while ($GLOBAL:job1.State -eq "Running")
                Write-Progress "Done" "Done" -completed
    
        Else
            {Write-Host "Local printer gather has completed" -ForegroundColor Yellow}
         }
        }
    
        Function ArchiveLog # Archives log files if they are greater than or equal to 1MB
        {
        # Creates the Variable which will hold the archive log naming convention
    
    
        if (test-path $Logfile) #If the logfile exists then determine if it needs to be archived
        {
            # Gets the log file if it is greater than oe equal to 1MB
            Get-ChildItem $LogFile -recurse | ? {($_.length/1MB) -ge 1} | % {
    
                # Archives the log File
                Move-Item $_.Fullname $archive
            }
        }
           else # If the log file does not exist
            {New-Item $Logfile -type File} # Create a new log file
        }
    
        Function LogI # Function Called to Write actions to the log file
        {
           # Accepts the parameter
           Param ([string]$logstring)
    
           # new line
           "`r`n"
    
           # Logs variable to the log file
           $logstring >> $LogFile
        }
    
        Function StartLog # Function called to format the beginning of each log file
        {
            LogI "**********Starting Log**********"
            LogI  "Log Date: $(Get-Date)"
        }
    
        Function EndLog # Function called to format the end of each log file
        {
            LogI "**********End Log**********"
            LogI  "Log Date: $(Get-Date)"
        } 
    
    
        Function CleanupTMP # Function called to cleanup all temp files created by this script
        {
            # Cleanup of existing build files
            $workingfiles = "C:\temp\ShareFile.txt", "C:\temp\pl.txt", "C:\temp\Localprinters.txt", "C:\temp\NewPrinters.txt", "C:\temp\ToDelete.txt", "C:\temp\working.txt"
    
        foreach ($file in $workingfiles) # Gets each file, deletes it 
            { 
            # Determines if the file in the path exists
             if (test-path $file) 
    
              { 
                echo Test-Path $file
                # If the file does exist, it deletes each one
                Remove-Item $file 
    
                # Writes the name of the deleted file to the log file
                LogI "Deleted File: $date $file" 
              }
    
            }
         }
    
        Function CleanupLogs # Removes Log files older than 14 days old
        {
            # set folder path
            $log_path = "C:\PrinterMaint\Archive*.log" 
    
            # set min age of files to 14 days
            $max_days = "-14"
    
            # determine how far back we go based on current date
            $del_date = $date.AddDays($max_days) 
    
            # Gets log files older than the $max_days defiled and Removes them
            Get-ChildItem $log_path -Recurse | Where-Object { $_.LastWriteTime -lt $del_date } | Remove-Item
            }
    
            Function BadPrinter # Function checks for indtalled printers with a status of 2, "Printer not Found on Server, unable to connect"
            {
            # Handle Bad Printers
    
            # Gathers Printers with status of 2 - Not Found on Server
            $GLOBAL:Bad = $GLOBAL:LPrinters | where {$_.printerstatus -eq 2} | select name | sort name
            #$GLOBAL:Bad2 = $GLOBAL:LPrinters | where {$_.printerstatus -eq 3 -and $_.name -ne "Microsoft XPS Document Writer"} | select name | sort name
            #$GLOBAL:Bad = $GLOBAL:Bad1 + $GLOBAL:Bad2
    
            if ($GLOBAL:Bad.count -gt 0) # If the array is greater than 0 then call the function to delete the printers
                {DelPrinter}
    
            Else
                {Write-Host "No printers will be deleted" -ForegroundColor Yellow
                LogI "$date No printers were deleted"}
        }
    
        Function DelPrinter # Function is called to delete printers if the array tests to be greater than 0
        {
            # Outputs the printers to a text file
            $GLOBAL:Bad | Out-File $DelFile
    
            # Assigns the text file contents to an array
            $btext = gc $DelFile
    
            # Removes the text file
            #remove-item $DelFile
    
        ##########################-Formatting-##########################################
        # Remove first four lines from the text file, spaces and blank lines
            $btext[0],$btext[3..($btext.length-1)] | out-file $DelFile -encoding ascii
            (gc $DelFile) | ? {$_.trim() -ne "" } | sc $DelFile -encoding ascii
            (gc $DelFile) | Foreach {$_.TrimEnd()} | sc $DelFile -encoding ascii
            (gc $DelFile) | where {$_ -ne ""} | sc $DelFile -encoding ascii
        ##########################-Formatting-###########################################
    
        # Removing a Network Printer Connection
        # Get the contents of the delete text file
        $GLOBAL:Bad = (gc $DelFile)
    
        # Reviews each item in the array and processes them seperately
        foreach ($B in $Bad)
        {
            # Reinitializes date for more accurate reporting
            $date2 = Get-Date
    
            # Assigns the date and time to the printer being deleted to a variable
            $LogDel = "$date2 $B"
    
            # Logs the deletion of the printer
            LogI "Deleted: $LogDel"
    
            # Networked printer is now deleted
            Write-Host "Deleting printer $B"
            (New-Object -ComObject WScript.Network).RemovePrinterConnection("$B")
         }
        }
    
        Function GNP # Function to Get Network Printers (GNP)
        {
            # Copies the printer map script to the local computer
            Copy-Item \\ShareDrive\Sharefolder\ShareFile.vbs C:\temp\ShareFile.txt
        }
    
        Function FNP
        {
            # Assign the contents of the Network printer list to a variable
                $NPrinters = Get-Content C:\temp\ShareFile.txt
        ##########################-Formatting-##########################################
            #removes all text and formatting from the network printer list then assigns the contents to a new array
            foreach ($NPrinter in $NPrinters) 
                {
                    $NPrinter1 = $NPrinter.split(" ")
                    $Printers = $NPrinter1[1]
                    $Printers1 = $($Printers -split '"')
                    $PL = $Printers1[1]|Where-Object {$_.length -gt 2}
                    $PL >> C:\temp\pl.txt
                }
        ##########################-Formatting-########################################## 
         }
    
         Function GIP
         {
            # Get the installed printers and write to a file
            $GLOBAL:LPrinters | select name | sort name  | Out-File C:\temp\LocalPrinters.txt
    
            # Get the contents of the file and load into an array
             $GLOBAL:ltext = gc C:\temp\Localprinters.txt
    
            # Remove the old file
            remove-item C:\temp\Localprinters.txt
         }
    
         Function FIP
         {    
    
          # Format the data in the array by removing the  first four lines and spaces from the array and output to the file
           $GLOBAL:ltext[0],$GLOBAL:ltext[3..($GLOBAL:ltext.length-1)] | out-file C:\temp\Localprinters.txt -encoding ascii
    
             # Removes blanks from the file and sets the contents with the new formatting
         (gc C:\temp\Localprinters.txt) | ? {$_.trim() -ne "" } | sc C:\temp\Localprinters.txt -encoding ascii
    
         # Removes the blank lines from the end of the file and sets the contents with the new formatting
         (gc C:\temp\Localprinters.txt) | ForEach {$_.trimEnd()} | sc C:\temp\Localprinters.txt -encoding ascii
    
         # Assigns the nice neat contents of the file back to the array
         $GLOBAL:ltext = (gc C:\temp\Localprinters.txt)
        }
    
         Function COMP
         {
        # Begins comparing the two printer files
            # Compares the files and outputs non-built printers to the NewPrinters.txt file
              $FinalGroups = Compare-Object (gc C:\temp\pl.txt) (gc C:\temp\LocalPrinters.txt) |
                where {$_.SideIndicator -eq "<="} |
                select -ExpandProperty inputObject |
                sort
                #Removes duplicate printers from the list using the -uniq
                $FinalGroups | select -uniq | Out-File C:\temp\NewPrinters.txt
                $GLOBAL:FinalPrinters = gc C:\temp\NewPrinters.txt
         }
    
         Function PNP
         {
        # Test new printer connectivity
    
        $PingFile = "C:\temp\NewPrinters.txt"
        $PingFile
        $Pings = gc $PingFile
    
        # Get just the printer names from the New Print File and appends them to a new file called Working
            foreach ($p in $Pings)
            {
                 $np = $p.split("\\")
                 $to = $np[3]
                 $to >> C:\temp\working.txt
            }
        # Assigns the contents of the working file (new printers) to an array
            $to = gc C:\temp\working.txt
    
            foreach ($t in $to)
                {
    
                    # Tests the printers connection
                     write-host "testing printer $t"
                     $ok = Test-Connection $t -Count 2 -Quiet
                    #Takes the connectivity results and determines to remove the printer from the file prior to build starting.  
                     if ($ok -ne "TRUE")
                        {
                            write-host "$t Communication Failed" -ForegroundColor Red
                            # If the printer communication fails, the entry is removed from the NewPrinters.txt file
                            (gc "C:\temp\NewPrinters.txt") -notmatch "$t" | Out-file "C:\temp\NewPrinters.txt"
    
                            # Logs the removal of the printer and why it is being removed
                            #Reinitializes date for more accurate times in the log file
                            $date11 = Get-Date
                            $remprt = "$date11 - printer $t will not be built - communication failed"
                            LogI $remprt
                        }
    
                    else
                        {
                            Write-Host "$t Communication Successful" -ForegroundColor Yellow
                        }
                 }
        }
    
        Function BUILD
        {
        # Build each new printer found in the NewPrinters text file
            $ToBuild = gc C:\temp\NewPrinters.txt
            foreach ($item in $ToBuild)
             {
    
                # Reinitialized date to get more accurate reporting
                    $date4 = Get-Date
                # Creates Logging info
                    $LogIt = "Created: $date4 $item"
    
                # Calls function to write information to a log file
                    LogI $LogIt 
    
                    Write-Host -NoNewLine "Creating printer $item" -ForegroundColor green
                # Printer Build now occurs
                    (New-Object -ComObject WScript.Network).AddWindowsPrinterConnection("$item")
            }
        }
    
    ##############
    ####-MAIN-####
    ##############
    
        # Cleanup High CPU and long running services which interfere with this script
        ServiceShutdown
    
        # Cycle the print spooler service    
        CycleSpooler
    
        # Get Local Printers
        GetLocalPrinters
    
        # Archive log maintenance
        ArchiveLog
    
        # Starts logging
        StartLog
    
        # Get the completed job
      `enter code here`  $GLOBAL:LPrinters = Receive-Job -job $GLOBAL:job1 -keep | select $props
    
        # Handles Bad pritners in a status of 2 "Printer not Found on Server, unable to connect"
        BadPrinter
    
        # Get Network printer list
        GNP
    
        # Format Network printer list
        FNP
    
        # Get installed/existing printers
        GIP
    
        # Format installed/existing printer file
        FIP
    
        # Compare existing printers with new printers only keep network printers needing to be built
        COMP
    
        # Check if New Printer File is NULL
        if ($GLOBAL:FinalPrinters.count -gt 0)
            {
                # Ping new printer connection and remove printers with failed connections
                  PNP
    
                # Build new printers
                  BUILD
            }
        Else
            {
                $date6 = Get-Date
                LogI "$date6 No new printers were built"
            }
    
        # Cleanup temp text files
        CleanupTMP
    
        # Stops Logging
        EndLog
    
        # Cleanup Archive log files older than the specified ## of days
        CleanupLogs
    
        # Restarts Services    
        ServiceReenable
    
        # Cycle the print spooler service    
        CycleSpooler
    
        # Printer Maintenance is Complete
        Write-Host "Printer Maintenance is complete" -ForegroundColor Red -BackgroundColor Yellow
    

    VBS内部的示例:

    Set objNetwork = CreateObject("WScript.Network")
    objNetwork.AddWindowsPrinterConnection "\\PrintServer\Printer1"
    

    我不控制也不维护此文件。我只被允许运行它。此脚本将.vbs复制到本地文本文件,然后根据需要进行编辑。

0 个答案:

没有答案