Delete specific printer

Good morning,

I need to remove or delete certain printers from client devices. I have written a script in Powershell and cloned and modified the Predefined procedure named “Run PowerShell script” to come up with the following complete script in C1. The script is supposed to delete the specific printer if it exists and then write a message to the Application event log.

 ps_content=r'''

# Description: This script removes specific printers

# Create new event log source if it does not exist
if (!([System.Diagnostics.EventLog]::SourceExists('System Administrator'))) 
    {
        # Register new source if source does NOT exist
        New-EventLog -LogName "Application" -Source "System Administrator"
    }

# Remove 'Send to OneNote*' printers if it exists 
if (Get-Printer -Name *onenote*) 
    {
        # Run this if printer exists
        $Printer = Get-Printer -Name *onenote*
        Remove-Printer -InputObject $Printer
        $Message = "The following printer was uninstalled by the System Administrator: " + $Printer.Name
    }

# Remove 'Fax' printers if it exists 
if (Get-Printer -Name *fax*) 
    {
        # Run this if printer exists
        $Printer = Get-Printer -Name *fax*
        Remove-Printer -InputObject $Printer
        $Message = "The following printer was uninstalled by the System Administrator: " + $Printer.Name
    }

# Remove 'XPS' printers if it exists 
if (Get-Printer -Name *XPS*) 
    {
        # Run this if printer exists
        $Printer = Get-Printer -Name *XPS*
        Remove-Printer -InputObject $Printer
        $Message = "The following printer was uninstalled by the System Administrator: " + $Printer.Name
    }

# Remove Canon MG3000 printer if it exists. This printer is used only by Leita.
if (Get-Printer -Name *MG3000*) 
    {
        # Run this if printer exists
        $Printer = Get-Printer -Name *MG3000*
        Remove-Printer -InputObject $Printer
        $Message = "The following printer was uninstalled by the System Administrator: " + $Printer.Name
    }

'''

import os

def ecmd(command):
    import ctypes
    from subprocess import PIPE, Popen

    class disable_file_system_redirection:
        _disable = ctypes.windll.kernel32.Wow64DisableWow64FsRedirection
        _revert = ctypes.windll.kernel32.Wow64RevertWow64FsRedirection
        def __enter__(self):
            self.old_value = ctypes.c_long()
            self.success = self._disable(ctypes.byref(self.old_value))
        def __exit__(self, type, value, traceback):
            if self.success:
                self._revert(self.old_value)

    with disable_file_system_redirection():
        obj = Popen(command, shell = True, stdout = PIPE, stderr = PIPE)
    out, err = obj.communicate()
    ret=obj.returncode
    if ret==0:
        if out:
            return out.strip()
        else:
            return ret
    else:
        if err:
            return err.strip()
        else:
            return ret

file_name='powershell_file.ps1'
file_path=os.path.join(os.environ['TEMP'], file_name)
with open(file_path, 'wb') as wr:
    wr.write(ps_content)

ecmd('powershell "Set-ExecutionPolicy RemoteSigned"')
print ecmd('powershell "%s"'%file_path)

os.remove(file_path)
 

When running the procedure with the logged in user (who are all local administrators), I see the following additional information in the log detail:

 
 File C:\Users\[User]\AppData\Local\Temp\powershell_file.ps1 cannot be loaded b ecause the execution of scripts is disabled on this system. Please see "get-hel p about_signing" for more details. At line:1 char:56 + C:\Users\[User]\AppData\Local\Temp\powershell_file.ps1 <<<<      + CategoryInfo          : NotSpecified: (:) [], PSSecurityException     + FullyQualifiedErrorId : RuntimeException 

How do I enable execution of scripts on all my network computers (Workgroup NOT domain) without having to enable on each device?
I am still testing and any interim assistance would be appreciated.

Hi @jeremy.r

We will analyze and update you once the script has been completed.

Thank you.

This procedure works if run as LocalSystem User, although there are no events logged in the Windows event log. I’ll take a look at this and post my version too, can’t hurt. :slight_smile:

@jeremy.r
I’ve attached my version of this script, which should be run as LocalSystem User in ITSM. Note that you’ll need to re-add the MG3000 to the printers list for your requirements, this version is generic and only removes OneNote/XPS/Fax.

Modifications:

  • Printers are created as an array, which makes it easier to add/remove entries as needed.
  • The script will search for the specified printers from the array and remove each one without requiring multiple If statements
  • Fixed the Windows Event Log entries so they are created successfully.
  • A message showing which printers have been uninstalled during the procedure run will be displayed in the ITSM Execution Log.
  • If no printers were found, a message stating such will also be displayed in the ITSM Execution Log.
Hope this helps, have a fantastic day. :)

20181017-Remove-specified-printers.json (3.45 KB)

This is awesome! Thank you very much for that. I’ve tested it on one PC and it works great. Nice touch to write back to ITSM console.
Have a lovely day too!

@jeremy.r ,

We are glad to know that it works. You are welcome.

So as I continue testing, I’ve needed to tweak the script but now experiencing some subsequent issues.
Unfortunately, PS 2.0 doesn’t have the Get-Printer cmdlet so I’ve had to use WMI instead to do what I need.
When I run the script below, it runs as Logged In User but not successfully as LocalSystem User.
Any direction?

ps_content=r'''
# Create list of printers which should be removed
$PrintersToRemove = @("*HP8764AD*", "*NPIBB0E4C*", "*MG3000*", "*OneNote*", "*XPS*", "*Fax*") 

# Create new event log source if it does not exist
if (!([System.Diagnostics.EventLog]::SourceExists('System Administrator'))) 
    {
        # Register new source if source does NOT exist
        New-EventLog -LogName "Application" -Source "System Administrator"
    }

# Search for specified printers on the system, remove them if found, and write an event to the event log and ITSM console.
foreach ($installedprinter in $PrintersToRemove) {
    $Printer = Get-WmiObject -Class Win32_Printer | Where-Object {$_.Name -LIKE $installedprinter}    
    $Message = "The following printer was uninstalled by the System Administrator: " + $Printer.Name
    If ($Printer) 
    {
        $Printer.Delete()        
        Write-EventLog -LogName "Application" -Source "System Administrator" -EventId "1000" -Message $Message
        Write-Host $Message
    }
    else
    {
       Write-Host "Printer not found -" $installedprinter
    }
}

'''

import os

def ecmd(command):
    import ctypes
    from subprocess import PIPE, Popen

    class disable_file_system_redirection:
        _disable = ctypes.windll.kernel32.Wow64DisableWow64FsRedirection
        _revert = ctypes.windll.kernel32.Wow64RevertWow64FsRedirection
        def __enter__(self):
            self.old_value = ctypes.c_long()
            self.success = self._disable(ctypes.byref(self.old_value))
        def __exit__(self, type, value, traceback):
            if self.success:
                self._revert(self.old_value)

    with disable_file_system_redirection():
        obj = Popen(command, shell = True, stdout = PIPE, stderr = PIPE)
    out, err = obj.communicate()
    ret=obj.returncode
    if ret==0:
        if out:
            return out.strip()
        else:
            return ret
    else:
        if err:
            return err.strip()
        else:
            return ret

file_name='remove_printers.ps1'
file_path=os.path.join(os.environ['TEMP'], file_name)
with open(file_path, 'wb') as wr:
    wr.write(ps_content)

ecmd('powershell "Set-ExecutionPolicy RemoteSigned"')
print ecmd('powershell "%s"'%file_path)

os.remove(file_path)

Hi @jeremy.r, I’ll take a look and see what I can figure out for you.