जांचें कि क्या Windows सेवा मौजूद है और PowerShell में हटाएं


148

मैं वर्तमान में एक परिनियोजन स्क्रिप्ट लिख रहा हूँ जो कई Windows सेवाएँ स्थापित करती है।

सेवाओं के नाम संस्करणित हैं, इसलिए मैं नई सेवा के इंस्टॉल के भाग के रूप में पूर्व विंडोज सेवा संस्करण को हटाना चाहता हूं।

मैं इसे PowerShell में सबसे अच्छा कैसे कर सकता हूं?

जवाबों:


235

आप इसके लिए WMI या अन्य टूल का उपयोग कर सकते हैं क्योंकि Remove-ServicePowershell 6.0 तक कोई cmdlet नहीं है ( निकालें-सेवा दस्तावेज़ देखें)

उदाहरण के लिए:

$service = Get-WmiObject -Class Win32_Service -Filter "Name='servicename'"
$service.delete()

या sc.exeउपकरण के साथ :

sc.exe delete ServiceName

अंत में, यदि आपके पास PowerShell 6.0 तक पहुंच है:

Remove-Service -Name ServiceName

2
आप इस उदाहरण के संबंधित भाग को पॉलीशेल (TransactedInstaller वर्ग का उपयोग करें) में भी पोर्ट कर सकते हैं: eggheadcafe.com/articles/20060104.asp हालांकि रविकांत का तरीका शायद सरल है।
जॉनएल

7
PS के अधिक हाल के संस्करणों में Remove-WmiObject है, और $ service.delete () के लिए साइलेंट विफलताओं से सावधान रहें - स्वरूपित उदाहरणों के साथ एक और उत्तर जोड़ा है।
स्ट्रैफ

1
संक्षेप में, अद्यतित संस्करण के लिए $service = Get-WmiObject -Class Win32_Service -Filter "Name='servicename'" $service | Remove-WmiObject
पॉवर्सशेल को

हर किसी की जानकारी के लिए, स्ट्रॉ का जवाब कहता है, "खामोश से सावधान रहें $service.delete()"
श्रीडंक

विंडोज पॉवरशेल 3.0 में शुरू होकर, गेट-सिम-इनस्टेमेंस द्वारा cmdlet Get-WmiObject को सुपरसीड किया गया है। तो आजकल आप ऐसा कर सकते हैं:Stop-Service 'servicename'; Get-CimInstance -ClassName Win32_Service -Filter "Name='servicename'" | Remove-CimInstance
रोसबर्ग लिन्हार्स

122

नौकरी के लिए सही उपकरण का उपयोग करने में कोई बुराई नहीं है, मुझे लगता है कि रनिंग (पावेरशेल से)

sc.exe \\server delete "MyService" 

सबसे भरोसेमंद तरीका जिसमें कई निर्भरताएं नहीं हैं।


55
.Exe भाग बहुत महत्वपूर्ण है क्योंकि sc अपने आप में Set-Content के लिए एक अन्य नाम है।
टॉम रॉबिन्सन

@tjrobinson इसके लिए धन्यवाद, .exeजब तक मैंने आपकी टिप्पणी नहीं देखी , तब तक मैं छोड़ चुका था । अब मेरे लिए काम कर रहा है।
gwin003

यह केवल तभी उपयोगी है जब आपके पास दूरस्थ कंप्यूटर के अधिकार हों। यदि नहीं (अधिकांश सुरक्षित वातावरणों की तरह) यह काम नहीं करेगा और आपको कुछ ऐसी चीज़ों की आवश्यकता होगी जो क्रेडेंशियल्स में पास करने का समर्थन करती हैं
डेविस्टेफेंस

\\serverयदि सेवा स्थानीय है तो सर्वर नाम ( ) केवल छोड़ा गया है।
jpmc26

1
यह बेहतर है क्योंकि यह अधिक आसानी से %और$_
चैम एलियाह


21

मैंने "-ErrorAction SilentlyContinue" समाधान का उपयोग किया लेकिन फिर बाद में इस समस्या में भाग गया कि यह एक ErrorRord को पीछे छोड़ देता है। तो यहाँ केवल जाँच के लिए एक और समाधान है कि क्या सेवा "गेट-सर्विस" का उपयोग कर रही है।

# Determines if a Service exists with a name as defined in $ServiceName.
# Returns a boolean $True or $False.
Function ServiceExists([string] $ServiceName) {
    [bool] $Return = $False
    # If you use just "Get-Service $ServiceName", it will return an error if 
    # the service didn't exist.  Trick Get-Service to return an array of 
    # Services, but only if the name exactly matches the $ServiceName.  
    # This way you can test if the array is emply.
    if ( Get-Service "$ServiceName*" -Include $ServiceName ) {
        $Return = $True
    }
    Return $Return
}

[bool] $thisServiceExists = ServiceExists "A Service Name"
$thisServiceExists 

लेकिन रविकांत के पास सबसे अच्छा समाधान है क्योंकि Get-WmiObject एक त्रुटि नहीं फेंकेगा यदि सेवा मौजूद नहीं थी। इसलिए मैं उपयोग करने पर बस गया:

Function ServiceExists([string] $ServiceName) {
    [bool] $Return = $False
    if ( Get-WmiObject -Class Win32_Service -Filter "Name='$ServiceName'" ) {
        $Return = $True
    }
    Return $Return
}

तो एक और अधिक पूर्ण समाधान की पेशकश करने के लिए:

# Deletes a Service with a name as defined in $ServiceName.
# Returns a boolean $True or $False.  $True if the Service didn't exist or was 
# successfully deleted after execution.
Function DeleteService([string] $ServiceName) {
    [bool] $Return = $False
    $Service = Get-WmiObject -Class Win32_Service -Filter "Name='$ServiceName'" 
    if ( $Service ) {
        $Service.Delete()
        if ( -Not ( ServiceExists $ServiceName ) ) {
            $Return = $True
        }
    } else {
        $Return = $True
    }
    Return $Return
}

7
मैंने पूर्णता के लिए Get-WmiObject -Class Win32_Service -Filter "Name='$serviceName'"और Get-Service $serviceName -ErrorAction Ignore(जो पूरी तरह से त्रुटि को छुपाता है) के बीच गति तुलना करने का फैसला किया । मुझे उम्मीद थी कि Get-WmiObject तेज हो सकता है क्योंकि यह कोई त्रुटि नहीं करता है। मैं बहुत गलत था। प्रत्येक को 100 बार लूप में लेकर, गेट-सर्विस ने 0.16 सेकंड का समय लिया, जबकि गेट-वमीओबजेक्ट ने 9.66 सेकंड का समय लिया। तो Get-Service, Get-WmiObject की तुलना में 60x तेज है।
साइमन तेवसी

13

PS के अधिक हाल के संस्करणों में Remove-WmiObject है। खामोशी से सावधान रहें $ service.delete () के लिए विफल ...

PS D:\> $s3=Get-WmiObject -Class Win32_Service -Filter "Name='TSATSvrSvc03'"

PS D:\> $s3.delete()
...
ReturnValue      : 2
...
PS D:\> $?
True
PS D:\> $LASTEXITCODE
0
PS D:\> $result=$s3.delete()

PS D:\> $result.ReturnValue
2

PS D:\> Remove-WmiObject -InputObject $s3
Remove-WmiObject : Access denied 
At line:1 char:1
+ Remove-WmiObject -InputObject $s3
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Remove-WmiObject], ManagementException
    + FullyQualifiedErrorId : RemoveWMIManagementException,Microsoft.PowerShell.Commands.RemoveWmiObject

PS D:\> 

अपनी स्थिति के लिए मुझे Administr ऐस एडमिनिस्ट्रेटर ’के रूप में चलने की आवश्यकता थी


7

Powershell 5.0 में कई सेवाओं को हटाने के लिए, क्योंकि इस संस्करण में निकालें सेवा मौजूद नहीं है

नीचे दिए गए आदेश चलाएँ

Get-Service -Displayname "*ServiceName*" | ForEach-object{ cmd /c  sc delete $_.Name}

5

दिमित्री और डीसीएक्स के उत्तरों को मिलाकर मैंने इसे बनाया:

function Confirm-WindowsServiceExists($name)
{   
    if (Get-Service $name -ErrorAction SilentlyContinue)
    {
        return $true
    }
    return $false
}

function Remove-WindowsServiceIfItExists($name)
{   
    $exists = Confirm-WindowsServiceExists $name
    if ($exists)
    {    
        sc.exe \\server delete $name
    }       
}

4

जहाँ-जहाँ वस्तु का उपयोग किया जा सकता था

if ((Get-Service | Where-Object {$_.Name -eq $serviceName}).length -eq 1) { "Service Exists" }


3

यह जाँचने के लिए कि क्या Windows नाम की कोई सेवा MySuperServiceVersion1मौजूद है, भले ही आप इसके सही नाम के बारे में सुनिश्चित न हों, आप एक वाइल्डकार्ड को नियोजित कर सकते हैं, जैसे कि एक विकल्प।

 if (Get-Service -Name "*SuperService*" -ErrorAction SilentlyContinue)
{
    # do something
}

3

एकल पीसी के लिए:

if (Get-Service "service_name" -ErrorAction 'SilentlyContinue'){(Get-WmiObject -Class Win32_Service -filter "Name='service_name'").delete()}

else{write-host "No service found."}

पीसी की सूची के लिए मैक्रो:

$name = "service_name"

$list = get-content list.txt

foreach ($server in $list) {

if (Get-Service "service_name" -computername $server -ErrorAction 'SilentlyContinue'){
(Get-WmiObject -Class Win32_Service -filter "Name='service_name'" -ComputerName $server).delete()}

else{write-host "No service $name found on $server."}

}

3

PowerShell Core ( v6 + ) में अब एक Remove-Servicecmdlet है

मैं इसे Windows PowerShell पर वापस पोर्ट करने की योजना के बारे में नहीं जानता , जहाँ यह v5.1 के रूप में उपलब्ध नहीं है।

उदाहरण:

# PowerShell *Core* only (v6+)
Remove-Service someservice

ध्यान दें कि यदि सेवा मौजूद नहीं है तो मंगलाचरण विफल हो जाता है, इसलिए केवल इसे हटाने के लिए यदि यह वर्तमान में मौजूद है, तो आप कर सकते हैं:

# PowerShell *Core* only (v6+)
$name = 'someservice'
if (Get-Service $name -ErrorAction Ignore) {
  Remove-Service $name
}

3
  • V6 से पहले PowerShell संस्करणों के लिए, आप यह कर सकते हैं:

    Stop-Service 'YourServiceName'; Get-CimInstance -ClassName Win32_Service -Filter "Name='YourServiceName'" | Remove-CimInstance
  • V6 + के लिए, आप Remove-Service cmdlet का उपयोग कर सकते हैं ।

देखें कि Windows PowerShell 3.0 में शुरू, Get-CimInstance द्वारा cmdlet Get-WmiObject को सुपरसीड किया गया है।


2

सर्वर की एक इनपुट सूची लेने के लिए इसे अपनाया, एक होस्टनाम निर्दिष्ट करें और कुछ सहायक आउटपुट दें

            $name = "<ServiceName>"
            $servers = Get-content servers.txt

            function Confirm-WindowsServiceExists($name)
            {   
                if (Get-Service -Name $name -Computername $server -ErrorAction Continue)
                {
                    Write-Host "$name Exists on $server"
                    return $true
                }
                    Write-Host "$name does not exist on $server"
                    return $false
            }

            function Remove-WindowsServiceIfItExists($name)
            {   
                $exists = Confirm-WindowsServiceExists $name
                if ($exists)
                {    
                    Write-host "Removing Service $name from $server"
                    sc.exe \\$server delete $name
                }       
            }

            ForEach ($server in $servers) {Remove-WindowsServiceIfItExists($name)}

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.