Retrieve Details of Deployed Solutions in SharePoint using PowerShell - sharepoint

I need to retrieve the details of all deployed SharePoint solutions, as are displayed in the Central Administration > Operations > Solution Management (AKA the Solution Store), using a PowerShell script (v2.0). Can anyone offer any guidance on how to retrieve this information from the SharePoint solution store via the SharePoint API?
Thanks, MagicAndi.

This is actually pretty easy to do. You conect to the SP Farm and just request get_Solutions.
Here is an example:
# Connect to the Farm
$SPfarm = [Microsoft.SharePoint.Administration.SPFarm]::get_Local()
# What Solution are we looking for?
$solution = "sharepointlearningkit.wsp";
# Get the solutions
$currentSolution = $SPfarm.get_Solutions() | Where-Object { $_.DisplayName -eq $solution; }
$currentSolution;

Based on Mitchell's answer, I have used:
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
function Get-LocalSPFarm()
{
return [Microsoft.SharePoint.Administration.SPFarm]::Local
}
function List-Solutions()
{
$farm = Get-LocalSPFarm
foreach ($solution in $farm.Solutions)
{
Write-Host($solution.DisplayName)
# Get-Member -InputObject $solution -MemberType property
}
}
All credit to Mitchell!

You can call stsadm.exe -o enumsolutions from your powershell script. It returns XML data which you can easily convert to [xml] data type and see whatever you need from that.
(stsadm lives in c:\Program Files\Common Files\Microsoft Shared\web server extensions\12\bin)
The output consists of statements similar to this
<Solution Name="yoursolution.wsp">
<Id>ab693dcd-6483-45ad-abba-9c996c67b6e0</Id>
<File>yoursolution.wsp</File>
<Deployed>TRUE</Deployed>
<WebApplicationSpecific>TRUE</WebApplicationSpecific>
<ContainsGlobalAssembly>TRUE</ContainsGlobalAssembly>
<ContainsCodeAccessSecurityPolicy>FALSE</ContainsCodeAccessSecurityPolicy>
<Deployment WebApplication="http://devserver/" />
<LastOperationResult>DeploymentSucceeded</LastOperationResult>
<LastOperationTime>10/26/2009 9:06 AM</LastOperationTime>
</Solution>

Here are three powershell cmdlets I use to pull back the solution information. Mine are simple compared to the ones above but I thought I would submit them anyway :)
In SP2010 Management Shell
To list all the solutions. Returns solution name, id and deployed status
Get-spsolutions
To list all the properties of a particular solution
get-spsolution -identity | select *
List all solutions, properties and output to a file to read :)
get-spsolution | select * | out-file c:\solutions.txt

Related

How to load > 1 million items to a SharePoint Online List

Can anyone suggest a reasonably practical and efficient way to load 1.2 million test items into a SharePoint Online list?
Background: We've decided to build a new application on top of SharePoint Online. Other application architecture options have all proved non-viable for various reasons. The application will use several SharePoint lists for persistence, one of which will be large, about 1.2 million items at peak. (Yes, we're planning ways to handle the 5000 item view limit.) To test viability of the architecture (including those view limit tactics) we need to create 1.2M test items in a list. Nothing we've tried has been practical:
Tried making POST calls to the REST API, with 5 concurrent threads so it will finish in a reasonable time. This fails after a bit with a HTTP 429 "Too many requests".
Tried uploading a spreadsheet with 1.2M rows. This fails at 130K entries each time, and I don't see a practical way to either upload / append to an existing list, nor to append items from one list to another existing list.
Tried running a Workflow (SharePoint 2013 variety, if that matters). This works but runs way too slow single threaded and I'm hesitant to try multiple concurrent workflows because this is a shared environment and if I trash the server that would be way not good.
Thanks in advance for any pointers!
You could try to use pnp powershell to add more than 1 million items.
$username = "amos#contoso.onmicrosoft.com"
$password = "password"
$cred = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $userName, $(convertto-securestring $Password -asplaintext -force)
Connect-PnPOnline -Url https://contoso.sharepoint.com/sites/dev -Credentials $cred
$ListName ="testn"
for($i=0;$i -lt 1000001;$i++){
Add-PnPListItem -List $ListName -Values #{"Title" = "test";}
}
Fastest way to load and process items from SPO using PnPPowershell goes something like following. Idea is to not initialize the items collection in any variable and directly process the items by page size.
Get-PnpListItem -List "{ListName}" -Fields "Field1","Field2","Fieldn" -PageSize 5000 | % {$i=0}{
% {$i=0}{
Do not move { to next line, I know it's weird but if you move, then good luck.
$item = $_
#Do your stuff with $item
Write-Host $item.Id
}

How to generate reports for Azure Log Activity Data using python for any resource alongwith 'Tags'?

My colleague used the below powershell query to retrieve log data for past 4 days excluding today which matches operations of the resources and collects features such as EventTimeStamp, Caller, SubscriptionId etc.
Get-AzureRmLog -StartTime (Get-Date).AddDays(-4) -EndTime (Get-Date).AddDays(-1) | Where-Object {$_.OperationName.LocalizedValue -match "Start|Stop|Restart|Create|Update|Delete"} |
Select-Object EventTimeStamp, Caller, SubscriptionId, #{name="Operation"; Expression = {$_.operationname.LocalizedValue}},
I am a newbie to azure and want to generate a report where I can also fetch the 'Tags' name & value against a resource for past 90 days in this report. What will be the powershell query for this? Can I also use python to query this data? I tried searching the documentation and was unable to dig into it, so if anybody could redirect me to the right place it will be helpful.
First of all, you should know that not all azure resources can specify tags, so you should consider this in your code. Please refer to Tag support for Azure resources to check which azure resource supports tags.
For powershell query, I suggest using the new azure powershell az module instead of the old azureRM module.
Here is a simple powershell code with az module. And for testing purpose, I just introduce how to fetch and add tags to the output. Please feel free to change it as per your requirement.
#for testing purpose, I just get the azure activity logs from a specified resource group
$mylogs = Get-AzLog -ResourceGroupName "a resource group name"
foreach($log in $mylogs)
{
if(($log.Properties.Content.Values -ne $null))
{
#the tags is contains in the Properties of the log entry.
$s = $log.Properties.Content.Values -as [string]
if($s.startswith("{"))
{
$log | Select-Object EventTimeStamp, Caller, SubscriptionId,#{name="Operation"; Expression = {$_.operationname.LocalizedValue}}, #{name="tags"; Expression = {($s | ConvertFrom-Json).tags}}
}
#if it does not contains tags.
else
{
$log | Select-Object EventTimeStamp, Caller, SubscriptionId,#{name="Operation"; Expression = {$_.operationname.LocalizedValue}}, #{name="tags"; Expression = {""}}
}
}
#if it does not contains tags.
else
{
$log | Select-Object EventTimeStamp, Caller, SubscriptionId,#{name="Operation"; Expression = {$_.operationname.LocalizedValue}}, #{name="tags"; Expression = {""}}
}
Write-Output "************************"
}
The test result:
For python, you can take a look at this github issue which introduces how to fetch logs from azure activity logs, but you need do some research on how to add tags to the output.
Hope it helps.

How to match any part of a property string using Where-Object

I have an array $array with many elements, an example looks like this:
ProfileID : 100
UID : 17
Name : SharePoint
Description : SharePoint Server Description
Now I am trying to filter by Name property, string to match is:
$string
SharePoint Policy Assignment
I have tried:
$array | Where-Object {$_.Name -like "$string"}
no match
$array | Where-Object {$_.Name -like "$string*"}
no match
$array | Where-Object {$_.Name -match "$string"}
no match
Is this possible using PowerShell? What am I missing?
The -like operator in PowerShell is used for a wildcard match, so you need to use the wildcard character, the asterisk, *.
Imagine this scenario, where I'm trying to match a particular Windows Service.
$svcs = Get-Service | Select-Object -first 15
C:\temp\blog> $svcs
Status Name DisplayName
------ ---- -----------
Stopped AJRouter AllJoyn Router Service
Stopped ALG Application Layer Gateway Service
Running AMD External Ev... AMD External Events Utility
Stopped AppIDSvc Application Identity
Running Appinfo Application Information
Stopped AppMgmt Application Management
Stopped AppReadiness App Readiness
Stopped AppVClient Microsoft App-V Client
Stopped AppXSvc AppX Deployment Service (AppXSVC)
Stopped aspnet_state ASP.NET State Service
Stopped AssignedAccessM... AssignedAccessManager Service
Running AsSysCtrlService ASUS System Control Service
Running AudioEndpointBu... Windows Audio Endpoint Builder
Running Audiosrv Windows Audio
Running AUEPLauncher AMD User Experience Program Launcher
To use the -Like operator to get a match, I have to provide a Wildcard Character, like this.
$svcs | Where-Object Name -like App*
Status Name DisplayName
------ ---- -----------
Stopped AppIDSvc Application Identity
Running Appinfo Application Information
Stopped AppMgmt Application Management
Stopped AppReadiness App Readiness
Stopped AppVClient Microsoft App-V Client
Stopped AppXSvc AppX Deployment Service (AppXSVC)
Try your operation using a WildCard, and I bet it will work :)
One other thing I noted, your $string is equal to SharePoint Policy Assignment, but the column you're comparing on of .Name is just SharePoint.
To complement FoxDeploy's helpful answer:
With collections that are already are in memory or easily fit, you can use member-access enumeration for a more convenient syntax that also results in much faster execution:
#($array.Name) -like $string # returns sub-array of matching elements
-like, when given an array as the LHS, acts as a filter: only those array elements that match the wildcard expression on the RHS are returned (also as an array).
Note the need for #(...) to ensure that $array.Name is an array, because a single-element array would result in the .Name property getting returned as a scalar (a single string), in which case -like would return a Boolean ($true or $false) rather than acting as a filter.
Also note that many PowerShell cmdlets directly support wildcard expressions as parameter values:
Taking Get-Service as an example, its (implied) -Name parameter supports wildcards:
Get-Service *router* # returns all services whose Name contains "router"
To determine a given cmdlet parameter's wildcard support:
PS> Get-Help Get-Service -Parameter Name
-Name <String[]>
Specifies the service names of services to be retrieved. Wildcards are permitted. By default, this cmdlet gets all of the services on the computer.
Required? false
Position? 1
Default value None
Accept pipeline input? True (ByPropertyName, ByValue)
Accept wildcard characters? false
It should be the Accept wildcard characters? value being true that indicates support for wildcard expressions, however, this is unfortunately not reliable, so also check the parameter description; here, the descriptin part Wildcards are permitted provides the information.
GitHub issue #4716 describes the problem and asks to make the programmatic discoverability of wildcard support reliable.

Azure Powershell - across MULTIPLE subscriptions in an EA

I have "billing reader" access to several hundred subscriptions in an EA.
I'm trying to get a list of virtual machines and their sizes across all subscriptions.
So currently when I run a "Get-AzureRMSubscription" it shows me all the subscriptions (hundreds of them), but i'm not sure how to actually run a script against all the subscriptions?
Would be great to get a "Get-AzureRMVM" across them all
Any suggestions?
Thanks in advance!
You can possibly do something like this:
$azureSubs = Get-AzureRMSubscription
$azureSubs | ForEach-Object {Select-AzureRMSubscription $_ | Out-Null; Get-AzureRMVM -WarningAction SilentlyContinue}
You are essentially setting an array variable to hold all your Azure Subscription and piping it to the ForEach-Object cmdlet to iterate all of the objects in the array. Then you pipe it to the Get-AzureRMVM cmdlet to list all VMs in each subscription.
This is definitely not optimized for performance and there might be better solutions out there, but at least you can run it and forget it.
The reason for the Out-Null and -WarningAction is to suppress the outputs you do not need.
You didn't ask but for classic resources we have the following script run on a regular basis and its output stored in a SQL Database.
$subscriptions = Get-AzureSubscription
foreach ($sub in $subscriptions)
{
$sub | Select-AzureSubscription
Get-AzureService | % {
Get-AzureDeployment -ServiceName $_.ServiceName
} | % {
New-Object -TypeName 'PSObject' -Property #{ 'ServiceName' = $_.ServiceName; 'Addresses' = $_.VirtualIPs.Address; }
} | sort Addresses | ft
}
% is ForEach-Object, ft is Format-Table although some kind souls may come along and try to edit this and make it harder to reuse. You can add/remove properties in the select statement to tailor your output as needed. Try it in one subscription to refined your needs, then create a script to make it easy to reuse.
We recently released Azure Resource Graph to support these types of searches across multiple subscriptions. See documentation here https://learn.microsoft.com/en-us/azure/governance/resource-graph/overview

Get SPWebTemplate from SPWeb

In my PowerShell script, I want to get the SPWebTemplate which has been used to create a SPWeb. In SPWeb instances, properties WebTemplate and WebTemplateId are accessible, but both of them dont identify a SPWebTemplate uniquely.
For example, if the SPWebTemplate "STS#0" has been used to create a SPWeb, WebTemplate would contain "STS" and WebTemplateId be "1".
Now
Get-SPWebTemplate | where { $_.ID -eq 1 }
would result in 3 results for each installed language (STS#0, STS#1, STS#2). How can I retrieve the correct SPWebTemplate-Name (STS#1)?
Thanks in advance,Jonas
Try SPWeb.Configuration.
This property has to be in the running for Most Poorly Named Property - SharePoint API. I remember trying to use WebTemplateId myself until I found Configuration (and I don't remember how I eventually found it).
You can try
$web = Get-SPWeb http://site/subsite
Get-SPWebTemplate | where {$_.name -like $web.WebTemplate+"*" } | where {$_.name -like "*"+$web.Configuration }
$web.Dispose()
But keep in mind that some $web.Configuration can be -1.

Resources