How to get service recovery options from Powershell? - powershell

I'm having issues figuring out an easy way to get the recovery options of a particular service in powershell.
Using command line sc: sc qfailure [servicename] [buffer size] works.
I also know that HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\\[service] will contain a FailureActions but i cant find any documentation on interpreting those values.
Is it just a matter of executing SC.EXE and parsing that data or is there a better way of doing this?

This will provide you Binary Value and you will have interpret it as follow which is tough part.
$actions = get-itemproperty hklm:\system\currentcontrolset\services\<ServiceShortName> | select -Expand FailureActions
typedef struct _SERVICE_FAILURE_ACTIONS {
DWORD dwResetPeriod;
LPTSTR lpRebootMsg;
LPTSTR lpCommand;
DWORD cActions;
SC_ACTION *lpsaActions;
} SERVICE_FAILURE_ACTIONS, *LPSERVICE_FAILURE_ACTIONS;
If you are using .NET
Follow this.

jborean93 has created a custom type that exposes the native C# service objects and methods to PowerShell. The included Get-ServiceRecovery and Set-ServiceRecovery functions make it easy to view and change service recovery settings within PowerShell.
https://gist.github.com/jborean93/889288b56087a2c5def7fa49b6a8a0ad
.\ServiceRecovery.ps1
(Get-ServiceRecovery -Name 'MyService').Actions

The ServiceController object that Get-Service doesn't contain all the properties for what a service can do.
To get access to more things try connecting to WMI. Try this command to see the properties we can see in WMI.
Get-WmiObject Win32_service | select -first 1 -property *

Related

Setting a DateTime to $null/empty using PowerShell and the SCSM cmdlets

I'm currently trying to sync additional attributes from the AD (Active Directory) for user objects in SCSM (System Center Service Manager) using a PowerShell script.
The extension I wrote for this, includes an attribute for the expiration date of a AD user account (DateTime value, named DateTimeAttribute in the example) if the user account doesn't expire it should be empty/null.
Using Import-SCSMInstance, which should be similar to a CSV import, it kind of works by passing "null" for the field. The problem is that Import-SCSMInstance seems to be quite unreliable and it doesn't offer any kind of information of why it works or doesn't work. Using Update-SCSMClassInstance seems to work a lot better but I can't figure out a way to clear the field using this and even using [DateTime]::MinValue will result in an error, stating that it's an invalid value.
So would anyone have an idea on how to clear the value using Update-SCSMClassInstance or figure out why Import-SCSMInstance might or might not work?
A simple example for this could look like the following:
$server = "<ServerName>"
$extensionGuid = "<GUID>"
Import-Module 'C:\Program Files\System Center 2012 R2\Service Manager\Powershell\System.Center.Service.Manager.psd1'
New-SCManagementGroupConnection -ComputerName $server
$extensionClass = Get-SCSMClass -Id $extensionGuid
$scsmUserObject = Get-SCSMClassInstance -Class $extensionClass -Filter 'UserName -eq "<User>"'
# Error
$scsmUserObject.DateTimeAttribute = ""
# Works but fails on Update-SCSMClassInstance
$scsmUserObject.DateTimeAttribute = $null
$scsmUserObject.DateTimeAttribute = [DateTime]::MinValue
# Works
$scsmUserObject.DateTimeAttribute = "01-01-1970"
Update-SCSMClassInstance -Instance $scsmUserObject
It seems that you can't clear a date once it's filled. When you write $null, it sets the date to 1-1-0001 01:00:00, which is an invalid date causing the update-scsmclassinstance to fail.
What we have set as a user's AD property when we don't want something to expire, is 2999-12-31 (yyyy-MM-dd). Perhaps this could help, although it's not directly what you asked for...
Also, you can use the pipeline to update a property in SCSM:
Get-SCSMClassInstance -Class $extensionClass -Filter 'UserName -eq "<User>"' | % {$_.DateTimeAttribute = <date>; $_} | update-scsmclassinstance
It doesn't look like it's currently possible to clear custom date attributes using the PowerShell cmdlets.

PowerShell Error - Method Not Found

When using $Computer.StartsWith("WI-") I get the following error
Method invocation failed because [Microsoft.ActiveDirectory.Management.ADComputer] does not contain a method named 'StartsWith'
I am under the impression that this is a default method. Is there something I have to import to use this?
Try this instead
$env:COMPUTERNAME.StartsWith("WI-")
That error is pretty clear: an object of [Microsoft.ActiveDirectory.Management.ADComputer] type does not contain a method named 'StartsWith'.
Where the $Computer comes from? From Get-ADComputer cmdlet? Read How to list all AD computer object properties
Running $Computer | Get-Member | ft -AutoSize should prompt more.
Run $Computer.GetType() as well. For instance, next could work if $Computer is not an array:
$Computer.Name.StartsWith("WI-")
$Computer.CN.StartsWith("WI-")
$Computer.DisplayName.StartsWith("WI-")
However, next similar expressions could give another results:
$Computer.Name.ToUpper().StartsWith("WI-")
$Computer.CN.ToUpper().StartsWith("WI-")
$Computer.DisplayName.ToUpper().StartsWith("WI-")

Powershell ADSI ntSecurityDescriptor

Hi I'm having some trouble getting the information on who joined the computer to the domain.
I can use this code but this is to be used by some non-administrative users that dont have access to the Powershell ActiveDirectory module.
Get-ADComputer myComputer -Properties ntSecurityDescriptor | Select ntSecurityDescriptor -ExpandProperty ntSecurityDescriptor
It's the owner property I am interested in here.
But now to the real deal
I need to make it work with ADSI
$Computer = [ADSI](([ADSISearcher]"(name=myComputer)").FindOne().Path)
$Computer.nTSecurityDescriptor
System.__ComObject
How do I "expand" the properties of the nTSecurityDescriptor using ADSI?
Powershell is smart enough that it will try to show you the best representation of an object with the most common properties it thinks you will need. Sometimes though you need to get the raw object underneath which you can do by using the PSBase property. Here's a link to Jeffrey Snover talking about it. Try this
$Computer = [ADSI](([ADSISearcher]"(name=myComputer)").FindOne().Path)
$Computer.PsBase.ObjectSecurity.Owner

Export-csv formatting. Powershell

Let's start off by saying that I'm quite new to Powershell and not the greatest one working with it's code and scripts but trying to learn. And now to the problem!
I'm working on a script that fetches information from computers in the network. I've got some code that works quite well for my purposes. But I'm having some problem when it comes to some information, mostly information that contains multiple objects, like service.
#This application will pull information from a list of devices. The devices list is
sent with C:\Users\test.txt and output is pushed to a file C:\Users\devices.csv
function kopiera
{
param
(
[Parameter(ValueFromPipeline=$true)]
[string[]]$Computer=$env:computername
)
Process
{
$computer | ForEach-Object{
$service=Get-WmiObject -Class Win32_Service -Computername $_
$prop= [ordered]#{
Service =$service.caption
}
New-Object PSCustomObject -Property $prop
}
}
}
Get-Content C:\Users\test.txt | kopiera | Export-csv c:\Users\devices.csv
When I export the csv file it looks like this:
TYPE System.Management.Automation.PSCustomObject
"Service"
"System.Object[]"
So it doesn't fetch the service.caption (Because there are too many?).
But If I replace the export-csv C:\Users\device.csv with out-file C:\Users\devices.txt it looks like this instead:
{Adobe Acrobat Update Service, Adobe Flash Player Update Service, Andrea ADI Filters Service, Application Experience...}
So it's starting to look better, but it doesn't get them all (Still because there are too many services?). What I'd like to do with this export/out-file is to get the information to appear vertically instead of horizontal.
(Wanted result)
Adobe Acrobat Service
Adobe Flash Player Update Service
and so on..
instead of:
(Actual result)
Adobe Acrobat Update Service, Adobe Flash Player Update Service, and so on...
Is there a way to make this possible, been trying for a while and can't wrap my brain around this.
Any help is appreciated!
CSV is not usually a good choice for exporting objects that contain multi-valued or complex properties. The object properties are going to be converted to a single string value. The only way to store an array of values is to convert it to a delimited string.
$prop= [ordered]#{
Service =($service.caption) -join ';'
}
will create a semi-colon delimited string, and you'll have to deal with splitting it back out in whatever appication is using the csv later.
If you want to save and re-import the original object with the property as an array, you can switch to Export-CLIXML instead of Export-CSV.

How to call a method with output parameters in PowerShell?

I'm working on a script to get started in PowerShell. I'm trying to convert a working VBScript script that enumerates mapped network drives on a remote Windows computer.
One of the tasks is to use remote WMI to read the registry and find the process owner of explorer.exe in order to determine who is logged in. This seems easy enough going by this guide.
However, the WMI method I need to call is GetOwner() from Win32_Process, which requires two output parameters to store its return value.
How can I call a method with output parameters? When I try to give it two strings, I get the error: Cannot find an overload for "GetOwner" and the argument count: "2".. The MSDN page says there are two parameters, so I'm not sure what I'm doing wrong.
Using the [ref] modifier:
SomeMethod( [ref] $a );
Notable blog entries
http://geekswithblogs.net/Lance/archive/2009/01/14/pass-by-reference-parameters-in-powershell.aspx
http://weblogs.asp.net/soever/archive/2009/03/26/powershell-return-values-from-a-function-through-reference-parameters.aspx
$explorer = gwmi Win32_Process -computerName computerName -filter "Name='explorer.exe' and SessionID=0"
$explorer.GetOwner() | select user,domain