uninstalling Office 2007 with PowerShell - powershell

I'm trying to write a script which uninstalls Microsoft Office 2007 Enterprise by grabbing the IdentifyingNumber using Get-WmiObject -Class Win32_Product. I'm able to grab the IdentifyingNumber, but when I attempt to uninstall PowerShell outputs some information that I'm not sure what to do with. Is this not a proper way to utilize Uninstall()?
$2k7 = Get-WmiObject -Class Win32_Product | Where-Object { $_.IdentifyingNumber -match "{90120000-0030-0000-0000-0000000FF1CE}" }
if ($2k7 -ne $null) {
$2k7.Uninstall()
}
else {
write-host "nothing to see here"
}
Output...
__GENUS : 2
__CLASS : __PARAMETERS
__SUPERCLASS :
__DYNASTY : __PARAMETERS
__RELPATH :
__PROPERTY_COUNT : 1
__DERIVATION : {}
__SERVER :
__NAMESPACE :
__PATH :
ReturnValue : 1603

Error 1603 is a catch-all error used by Microsoft Installer when an unexpected failure is encountered.
I would verify that you're running your Powershell window with elevated privileges and that the program you intend to uninstall doesn't have any processes currently running.

Related

Change RDP with Invoke-WmiMethod

I want change RDP port with WMI method but my code doesn't work and I don't know why.
Invoke-WmiMethod -Class StdRegprov -Name SetDWORDvalue -ArgumentList 2147483650,"System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp", "PortNumber", 3354
I get this after execute in PowerShell:
__GENUS : 2
__CLASS : __PARAMETERS
__SUPERCLASS :
__DYNASTY : __PARAMETERS
__RELPATH :
__PROPERTY_COUNT : 1
__DERIVATION : {}
__SERVER :
__NAMESPACE :
__PATH :
ReturnValue : 5
PSComputerName :
But nothing changed?
This right here indicates your problem:
ReturnValue : 5
Return code 5 means "access denied". Your user does not have permission to write to that registry location. You probably need to run the code "as administrator".
With that said, PowerShell provides direct access to the registry. You don't need WMI for that.
$reg = 'HKLM:\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp'
$name = 'PortNumber'
$value = 3354
New-ItemProperty -Path $reg -Name $name -Value $value -Type DWORD -Force | Out-Null
You still need to run this with a user who has write access to the registry key, though.

Output after removing programs using WMI - Powershell

I'm using WMI to uninstall software remotely and it's working fine to remove the software. What I'm struggling with is using the results of that (Successful or not) to give a simple out put message rather than the normal output of the command. I normally use $lastexitcode for this but no matter whether or not the command succeeds it runs to my successful uninstall message. Here's what I'm trying to use:
$app = Get-WmiObject Win32_Product -ComputerName "$computer" | where { $_.vendor -eq "APN, LLC" }
$app.Uninstall()
if ($lastexitcode -eq 0)
{
write-host -ForegroundColor Green "Programm Successfully Removed"
}
else
{
write-host -ForegroundColor red "There was a problem uninstalling the program"
}
When I leave output of the operation on it returns:
__GENUS : 2
__CLASS : __PARAMETERS
__SUPERCLASS :
__DYNASTY : __PARAMETERS
__RELPATH :
__PROPERTY_COUNT : 1
__DERIVATION : {}
__SERVER :
__NAMESPACE :
__PATH :
ReturnValue : 0
PSComputerName :
I figure I could do something with the ReturnValue but I'm not sure how. Any help would be greatly appreciated.
EDIT: The solution thanks to Bruce's answer:
$app = Get-WmiObject Win32_Product -ComputerName "$computer" | where { $_.vendor -eq "APN, LLC" }
$appuninstall = $app.Uninstall()
if ($appuninstall.returnvalue -eq 0)
{
write-host -ForegroundColor Green "Programm Successfully Removed"
}
else
{
write-host -ForegroundColor red "There was a problem uninstalling the program"
}
$LastExitCode is only set when running native commands (external .exes). In your code, you want to capture the result of the call to Uninstall() in a variable then use the return code property from that object in your if statement.

How to use powershell.exe with -Command using a scriptblock and parameters

For reasons that should not impact the current question I need to run a script, with the definition and parameters outside the command, inside a different PowerShell instance, without using PSSessions, background jobs or files (I have working examples for PSSession, background jobs and .ps1 files and I'm aware they can replace what I'm trying to do, but I need a working example with powershell.exe -Command as well).
I looked at the help for powershell.exe, and it should support what I am trying to do, but I can't get it working with all that I need (script definition and parameters outside the command).
As a working example I have:
$abc = powershell.exe -WindowStyle Hidden -NonInteractive -Command {Invoke-Command -ScriptBlock {
param($a1,$a2)
$a1*6
$a2*5} -Argumentlist #(8,'abc')}
I need to be able to at least move the -ArgumentList outside the command, like:
$abc = powershell.exe -WindowStyle Hidden -NonInteractive -Command {Invoke-Command -ScriptBlock {
param($a1,$a2)
$a1*6
$a2*5} -Argumentlist #($args[0],$args[1])} -args #(8,'abc')
and even better have:
$script={
param($a1,$a2)
$a1*6
$a2*5}
$args=#(8,'abc')
$abc = powershell.exe -WindowStyle Hidden -NonInteractive -Command $script -args $args
I already looked at the following similar questions, but couldn't find what I needed:
How to run a Powershell script from the command line and pass a directory as a parameter
How can I Start-Process powershell.exe with some string splitter?
Not sure if this helps I added a few things to your original script and changed $args to $z and it seemed to work.
$script={
param($a1 =1 ,$a2 = 2)
$a1*6
$a2*5
test-connection -Count 2 www.google.com
Write-Output $a1
Write-Output $a2
}
$z=#(8,'abc')
$abc = powershell.exe -WindowStyle Hidden -NonInteractive -Command $script -args $z
$abc
48
abcabcabcabcabc
PSComputerName : ok
IPV4Address :1.1.1.4
IPV6Address :
__GENUS : 2
__CLASS : Win32_PingStatus
__SUPERCLASS :
__DYNASTY : Win32_PingStatus
__RELPATH : Win32_PingStatus.Address="www.google.com",BufferSize=32,NoFragmentation=FALSE,RecordRoute=0,ResolveAddressNames=FALSE,SourceRou
te="",SourceRouteType=0,Timeout=4000,TimestampRoute=0,TimeToLive=80,TypeofService=0
__PROPERTY_COUNT : 24
__DERIVATION : {}
__SERVER : ok
__NAMESPACE : root\cimv2
__PATH : \\ok\root\cimv2:Win32_PingStatus.Address="www.google.com",BufferSize=32,NoFragmentation=FALSE,RecordRoute=0,ResolveAddressName
s=FALSE,SourceRoute="",SourceRouteType=0,Timeout=4000,TimestampRoute=0,TimeToLive=80,TypeofService=0
Address : www.google.com
BufferSize : 32
NoFragmentation : False
PrimaryAddressResolutionStatus : 0
ProtocolAddress :1.1.1.4
ProtocolAddressResolved :
RecordRoute : 0
ReplyInconsistency : False
ReplySize : 32
ResolveAddressNames : False
ResponseTime : 19
ResponseTimeToLive : 252
RouteRecord :
RouteRecordResolved :
SourceRoute :
SourceRouteType : 0
StatusCode : 0
Timeout : 4000
TimeStampRecord :
TimeStampRecordAddress :
TimeStampRecordAddressResolved :
TimestampRoute : 0
TimeToLive : 80
TypeofService : 0
PSComputerName : ok
IPV4Address :1.1.1.4
IPV6Address :
__GENUS : 2
__CLASS : Win32_PingStatus
__SUPERCLASS :
__DYNASTY : Win32_PingStatus
__RELPATH : Win32_PingStatus.Address="www.google.com",BufferSize=32,NoFragmentation=FALSE,RecordRoute=0,ResolveAddressNames=FALSE,SourceRou
te="",SourceRouteType=0,Timeout=4000,TimestampRoute=0,TimeToLive=80,TypeofService=0
__PROPERTY_COUNT : 24
__DERIVATION : {}
__SERVER : ok
__NAMESPACE : root\cimv2
__PATH : \\ok\root\cimv2:Win32_PingStatus.Address="www.google.com",BufferSize=32,NoFragmentation=FALSE,RecordRoute=0,ResolveAddressName
s=FALSE,SourceRoute="",SourceRouteType=0,Timeout=4000,TimestampRoute=0,TimeToLive=80,TypeofService=0
Address : www.google.com
BufferSize : 32
NoFragmentation : False
PrimaryAddressResolutionStatus : 0
ProtocolAddress :1.1.1.4
ProtocolAddressResolved :
RecordRoute : 0
ReplyInconsistency : False
ReplySize : 32
ResolveAddressNames : False
ResponseTime : 21
ResponseTimeToLive : 252
RouteRecord :
RouteRecordResolved :
SourceRoute :
SourceRouteType : 0
StatusCode : 0
Timeout : 4000
TimeStampRecord :
TimeStampRecordAddress :
TimeStampRecordAddressResolved :
TimestampRoute : 0
TimeToLive : 80
TypeofService : 0
8
abc
This answer isn't 100% relevant to the original poster, because they are trying to run PowerShell from within PowerShell. I am trying to run it PowerShell from either a command prompt, or specifically WMI. A little background: the reason I'm trying to do this is because PowerShell remoting is not enabled on my target machine and I want to enable it. I can't use winrm because it requires user input. So, this works:
$x=Get-WmiObject -ComputerName "<computer name>" -Namespace "root\cimv2" -Class "Win32_Process" -List
$x.Create('C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -Command "& C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -Command {Enable-PSRemoting}"',$null,$null)
Results:
__GENUS : 2
__CLASS : __PARAMETERS
__SUPERCLASS :
__DYNASTY : __PARAMETERS
__RELPATH :
__PROPERTY_COUNT : 2
__DERIVATION : {}
__SERVER :
__NAMESPACE :
__PATH :
ProcessId : 12508
ReturnValue : 0
PSComputerName :
I should probably post this in a different question, but this one came up on a google search for "how to pass scriptblock to powershell.exe", so I thought it would be useful here.

Create shared folder with [WMICLASS]"Win32_Share"

I'm using a PowerShell script that creates local share folder.
function shareCacheFolder() {
  $Sharename = 'cacheFolder'
  $Foldername = 'c:\cacheFolder'
  if (!(Get-WmiObject Win32_Share -Filter "name='$Sharename'")) {
    $Shares = [WMICLASS]"Win32_Share"
    $Shares.Create($Foldername, $Sharename, 0)
  }
}
This seems to work on most machines. But not on mine.
I'm getting this output:
__GENUS : 2
__CLASS : __PARAMETERS
__SUPERCLASS :
__DYNASTY : __PARAMETERS
__RELPATH :
__PROPERTY_COUNT : 1
__DERIVATION : {}
__SERVER :
__NAMESPACE :
__PATH :
ReturnValue : 8
PSComputerName :
I've also tried using this convention:
function shareCacheFolder() {
$path = "c:\cachefolder"
$name = "cachefolder"
$type = 0
$password = ""
$description = ""
$max = 100
$access = $null
  if (!(Get-WmiObject Win32_Share -Filter "name='$Sharename'")) {
Invoke-WmiMethod -Class Win32_Share -Name Create -ArgumentList $access, $description, $max, $name, $password, $path, $type
  }
}
I'm using PowerShell version 3.
As documented the return code 8 means "unknown error". The command is syntactically correct and works on other computers, so the issue is not with your code. The problem is also unlikely to be caused by a share name conflict, missing folder, permission issue, etc., as those would cause different errors/return codes.
I suspect that on your system the Server service is not running. Verify that with the following command:
Get-Service 'Server' | Select-Object StartType, Status | Format-List
The start type should be "Automatic", and the status should be "Running". If they're not, change the start type and start the service like this:
Get-Service 'Server' | Set-Service -StartupType 'Automatic'
Start-Service 'Server'

CommandNotFoundException: get-windowsoptionalfeature

I am using Powershell Version 2 on windows 7. I need to run the following command: get-windowsoptionalfeature
but when I run: get-command -Verb Get, the get-windowsoptionalfeature is not listed and as a result when I enter the command I receive an error stating that "get-windowsoptionalfeature" is not recognized as the name of a cmdlet, function.
Am I missing a dll or something?
get-windowsoptionalfeature is only applicable to Windows 8 & Server 2012.
try this in powershell console
PS C:\>$feature=Get-WmiObject -query "select * from Win32_OptionalFeature"
Now $feature is array of object of type ManagementObject.
to prove it try
PS C:\> $feature[0]
this is what I get.
__GENUS : 2
__CLASS : Win32_OptionalFeature
__SUPERCLASS : CIM_LogicalElement
__DYNASTY : CIM_ManagedSystemElement
__RELPATH : Win32_OptionalFeature.Name="OEMHelpCustomization"
__PROPERTY_COUNT : 6
__DERIVATION : {CIM_LogicalElement, CIM_ManagedSystemElement}
__SERVER : TTL001343
__NAMESPACE : root\cimv2
__PATH : \\TTL001343\root\cimv2:Win32_OptionalFeature.Name="OEMHelpCustomization"
Caption :
Description :
InstallDate :
InstallState : 2
Name : OEMHelpCustomization
Status :
You can get query specific objects as well.
example:
PS C:\>$feature=Get-WmiObject -query "select * from Win32_OptionalFeature where name = 'RemoteServerAdministrationTools-Roles-AD-Powershell'"
Now this will be single object not an array.
There's the Client Manager Module:
http://archive.msdn.microsoft.com/PSClientManager