I've got a command that can list all app pools on a machine:
Get-WmiObject -namespace "root/MicrosoftIISv2" -class IIsApplicationPool |Select-Object -property #{N="Name";E={$name = $_.Name; $name.Split("/")[2] }} | Format-Table
I want to set the managedpipeline of every app pool on the box. I've tried this:
Get-WmiObject -namespace "root/MicrosoftIISv2" -class IIsApplicationPool |Select-Object -property #{N="Name";E={$name = $_.Name; $name.Split("/")[2] }} | ForEach-Object {cmd /c "c:\windows\system32\inetsvr\appcmd.exe set apppool $name /managedPipleineMode:"Classic"'}
This is giving me a "cannot find the path specified" error. Any ideas how I can this to work?
In order to set the Managed Pipeline mode (or any property of the AppPool), you need to use Set-ItemProperty. But it gets more fun than that:
Set-ItemProperty takes a Path as its input. Get-ChildItem will
return you a collection of ConfigurationElement objects, not Path
strings.
ManagedPipelineMode is internally stored as an integer, so
you have to know the correct "magic" number to pass in.
Fortunately, that is documented here, in the "Remarks" section.
This did the trick for me:
Import-Module WebAdministration
Get-ChildItem IIS:\AppPools |
Select-Object -ExpandProperty PSPath |
ForEach-Object { Set-ItemProperty $_ ManagedPipelineMode 1 }
following the documentation :
$iisAppPoolName = "MyPool"
$appPool = New-WebAppPool -Name $iisAppPoolName
$appPool.managedPipelineMode = "Classic"
$appPool |Set-Item
I tested, IIS 8.0, Windows server 2012, and it works.
If you're on Powershell V2 I would use the WebAdministration module e.g. from an elevated prompt:
Import-Module WebAdministration
Get-ChildItem IIS:\AppPools | Foreach {$_.ManagedPipelineMode = 'Classic'}
Related
I have created a PowerShell script that retrieves the following;
RegKey value "Servername"
Regkey value "ServerListName"
Regkey Value "Version"
Wmi-Object "Computername"
I would like to run this against a list of computers and export the values to a csv file or append the source csv file.
I can get the information to display on the screen but am having difficulty exporting and adding Titles for each of the returned results.
Clear-Host
$computers = Get-Content C:\Tanium.csv
foreach ($computer in $computers)
{
$RegKey ="Software\WOW6432Node\Tanium\Tanium Client"
Cd hklm:\$RegKey
Get-WMIObject Win32_ComputerSystem | Select-Object -ExpandProperty name
Get-ItemPropertyValue -Path. -Name ServerName
Get-ItemPropertyValue -Path. -Name ServerNameList
Get-ItemPropertyValue -Path. -Name Version
}
I would like to either export or append the existing csv file displaying data as follows if possible;
ComputerName: 123455
Version: 7.098
ServerName: 1233456454
ServerNameList: 1233456454
Assuming that PowerShell remoting is set up on all target computers:
$computers = Get-Content C:\Tanium.csv
Invoke-Command -Computer $computers {
$regKey = "HKLM:\Software\WOW6432Node\Tanium\Tanium Client"
$regKeyValues = Get-ItemProperty -LiteralPath $regKey
[pscustomobject] #{
ComputerName = (Get-CimInstance Cim_ComputerSystem).Name
Version = $regKeyValues.Version
ServerName = $regKeyValues.ServerName
ServerNameList = $regKeyValues. ServerNameList
}
} | Export-Csv -Append -NoTypeInformation -Encoding Utf8 -LiteralPath out.csv
Note:
I've switched from WMI to CIM cmdlets, given that CIM supersedes WMI in PSv3+.
The output order of the custom objects doesn't necessarily reflect the input order of computer names ($computers).
I have this script that changes services per a csv file input
Import-CSV .\SSAS_services.csv |
ForEach-Object{
Get-Service $_.Service -ComputerName $_.Server -PipelineVariable svc|
Set-Service -Status $_.Task -StartupType $_.'Startup Type' -PassThru
} |
Select-Object MachineName, Name, Status, StartType, #{n='OldStatus';e={$svc.Status}}, #{n='OldStartType';e={$svc.StartType}} |
tee-object -FilePath '.\ChangeServices_LOG.txt' #-Append
Server,Service,Startup Type,Task
DCVPIM108,SQL Server Analysis Services (MSSQLSERVER),automatic,start
server2,"SQL Server Analysis Services (MSSQLSERVER), SQL Server Analysis Services (MSSQLSERVER) CEIP",Manual,stop
it works great, except for my -PipelineVariable svcis not working as intended. if a service was "stopped" and "Manual" before being changed to "running" and "automatic", it doesnt get the old values "stopped" and "Manual" for OldStatus and OldStartType
MachineName : DCVPIM108
Name : MSSQLServerOLAPService
Status : Running
StartType : Automatic
OldStatus : Running
OldStartType : Automatic
why is that?
The -PipelineVariable / -pv common parameter only works:
within a single pipeline.
in script blocks in later segments of the same pipeline.
Since you're using it in a pipeline that is nested inside the ForEach-Object script block, the commands in the outer pipeline cannot use it.
However, I suggest restructuring your command so that you don't need a pipeline variable for Get-Service anymore.
Instead,
-PipelineVariable $csvRow is used with Import-Csv, so that you can more easily refer to it even in nested pipelines (the alternative would be to define the variable explicitly at the start of the ForEach-Object script block as $csvRow = $_).
$svc is then declared as an -OutVariable, so that the original service state is captured before Set-Service is called to change it.
Getting a service, setting its startup type, and enriching the CSV-row object with additional information now all happen inside the ForEach-Object script block.
Import-CSV .\SSAS_services.csv -PipelineVariable csvRow | ForEach-Object {
Get-Service -Name $csvRow.Service -ComputerName $csvRow.Server -OutVariable svc |
Set-Service -Status $csvRow.Task -StartupType $csvRow.'Startup Type'
$csvRow | Select-Object MachineName, Name, Status, StartType,
#{n='OldStatus';e={$svc.Status}},
#{n='OldStartType';e={$svc.StartType}}
} | Tee-object -FilePath '.\ChangeServices_LOG.txt'
I guess what you want is to pass same object down the multiple pipes. I haven't use -PipeLineVariable much, but looks like it just creating a nicer alias for $_ . If you need to push something specific down the pipeline I guess you need to use write-ouput with custom object or hashtable. Below is a dummy sample, pushing down and modifying a hastable:
$services = "xagt" , "xbgm" , "XblGameSave"
$list = new-object System.Collections.ArrayList
$serv | foreach {
$svc = Get-Service $_ ; Write-Output #{Name = $svc.Name; Stat=$svc.Status}
} | foreach {$_.SomeNewItem = "new stuff"; $list.Add($_)}
But in your case one pipeline might be sufficient. Try something like that:
Import-CSV .\SSAS_services.csv | foreach {
$old = Get-Service $_.Service;
Set-Service -Name $_.Service -Status Running
$new = Get-Service $_.Service;
$data = $_.MachineName, $_.Service, $old.Status, $new.Status -join ","
Write-Host $data
$data >> Log.txt
}
So I've been over at
https://blogs.technet.microsoft.com/heyscriptingguy/2013/11/15/use-powershell-to-find-installed-software/
trying to use this to get a list of installed programs on a remote machine. I already started the WinRM remotely via PS, and am using the command
Invoke-Command -cn MC-PKS-MCARDH-L -ScriptBlock {
Get-ItemProperty HKLM:\Software\Wow6432Node\* |
select PSPath, PSParentPath, PSChildName
}
The primary use of this is to get the Adobe versions of programs on the client's PC, but for some reason this doesn't return many of the folders. It just returns HP, ESRI, Malwarebytes, and a few others:
PSPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\Software\Wow6432Node\ESRI
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\Software\Wow6432Node
PSChildName : ESRI
PSComputerName : mc-pks-mcardh-l
RunspaceId : 76050648-eec5-4e90-960d-872264a894d4
PSShowComputerName : True
Any reason this is? I tried using the one from the page I linked:
HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*
but Adobe Reader doesn't even show up on that list.
I'm an AD Admin on the domain so why is it not showing all the folders? I'm looking via regedit now on the test machin and theres a folder called Adobe.
I'd recommend using, or at least trying, WMI:
Get-WmiObject -Class Win32_Product | Select-Object -Property Name, Vendor, Version | Format-Table;
You can also specify -ComputerName to query a remote machine.
To list all properties for dev. purposes, try:
Get-WmiObject -Class Win32_Product | Format-List -Property *;
Good luck!
--- ALTERNATIVELY, please try:
[String] $strKey = '';
[String] $strSubKey = '';
[PSCustomObject] $objData = $null;
#( 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall', 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall' ) | Foreach-Object {
$strKey = $_;
Get-ChildItem -Path $strKey | Select-Object -ExpandProperty PSChildName | Foreach-Object {
$strSubKey = $_;
$objData = Get-ItemProperty -LiteralPath (Join-Path -Path $strKey -ChildPath $strSubKey) | Select-Object -Property DisplayName, DisplayVersion;
if ( $objData.DisplayName -ne $null ) {
Write-Output -InputObject $objData;
} #if
} #Foreach-Object
} #Foreach-Object
I'm sure this should be straight forward but I've been stuck on it for a while now...
I am trying to get the service names (for sql server) into an array but can't figure out how to do it. I basically want the array contents to look something like the output of this:
Get-Service -computername $server_name -name sql* | format-table -property name
I have tried things like this but the contents of $service_name are very odd:
$service_name = (Get-Service -computername $server_name -name sql* -exclude *sqlwriter | format-table -property name)
Whatever I try either errors or gives some strange message in my array. Should this be easy/possible? I'm guessing I could dump the results in a text file then use the contents of that but it's a bit messy and more overhead than seems necessary.
Not sure, but where you looking for this (with whatever variation on the pattern for -Name and/or -Exclude)?
PS> $names = (Get-Service -Name Sql* | select name)
PS> $names.GetType().IsArray
True
PS> $names.Length
3
PS> $names
Name
----
SQLBrowser
SQLSERVERAGENT
SQLWriter
Or even along the lines of the following if you really want the "Name" as a System.String array.
PS> $names = (Get-Service -Name Sql* | foreach { $_.Name -as [string]})
PS> $names[0].GetType().FullName
System.String
PS> $names
SQLBrowser
SQLSERVERAGENT
SQLWriter
But also keep the good advice in #alroc's answer in mind - maybe you want to keep the actual type of Get-Service's result (System.ServiceProcess.ServiceController) as long as possible and access/use the Name property of it as late as possible. YMMV.
You're using format-table in the pipeline. Anytime you use a format-* cmdlet, that's the end of the line for your data - it's now just a formatted bunch of text, it's no longer data that you can actually use.
Try this to get the names formatted as a table for viewing:
$service_name = (Get-Service -computername $server_name -name sql* -exclude *sqlwriter);
$service_name | format-table -property name;
That said, I ran both your version and mine above and got the same visual output - the critical difference is that mine stores data in $service_name, not just a bunch of text (as yours does).
edit:
In response to:
All I really needed was the service names in an array to then use elsewhere
$service_name = (Get-Service -computername $server_name -name sql* -exclude *sqlwriter) | select-object -expandproperty name;
or:
$service_name = (Get-Service -computername $server_name -name sql* -exclude *sqlwriter).name;
No need to invoke WMI directly.
How can i add the server name at the left of each line result on this script?. Thank you!
$servers = Get-Content -path .\Machines.txt
[pscustomobject]$result = #()
$subresult =
ForEach ($server in $servers)
{
Set-Service -computername $servers -Name sacsvr -StartupType Disabled -PassThru
}
$result = $subresult
$result | Out-File local_group_members.csv
This is an example result:
Status Name DisplayName
------ ---- -----------
Stopped sacsvr Special Administration Console Helper
Stopped sacsvr Special Administration Console Helper
Stopped sacsvr Special Administration Console Helper
Alternatively you can just add a property to the objects you're outputting right now. Pipe your Set-Service to Add-Member like this:
Set-Service -computername $servers -Name sacsvr -StartupType Disabled -PassThru | Add-Member -MemberType NoteProperty -Name 'Server' -Value $Server -PassThru
Now each object that you pass to $subresult has a new property Server that is the name of the server it was run on. You'll probably want to pipe through Select when outputting to have the order you want.
$SubResult | Select Server, Status, Name, DisplayName | Export-CSV 'local_group_members.csv' -NoType
You can arbitrarily re-order or add to your output with Select-Object. You can use hash tables to include calculated properties such as your desired ServerName.
So for each server, you can set the services and tag the output with that server name:
ForEach ($server in $servers)
{
Set-Service -computername $server -Name sacsvr -StartupType Disabled -PassThru |
Select #{Name = 'ServerName'; Expression = {$server}}, Name, DisplayName, Status
}
The above is shorthand for:
Select-Object -Property (properties)
The -Property parameter allows you to select any arbitrary grouping of properties on the type of object being piped in. Another parameter, -InputObject allows us to pipe in objects by value.