How are exported Azure Automation Graphical Runbook definition (.graphrunbook) encoded/encrypted? - powershell

This is the (trimmed) content of a .graphrunbook after Exported from the Azure Portal.
{
"SchemaVersion" : "1.2",
"RunbookDefinition" : "AAA....AAA="
}
The runbook definition is presumably XML- or XAML-based, and while this looks like base64 encoded text, decoding it as such results in large portions that are still encoded/illegible.
Context: I'm working on a revamped version of the Sync-VsoGitRunbook that works with ARM, doesn't require an arbitrary folder hierarchy (by automatically determining dependencies), and can deploy graphical runbooks as well - because why not! This is all pretty much wrapped up for Native & Workflow, these are just the last piece to implement.
I'm not using any graphical runbooks currently, but if/once we do, I want them to fall in line with the architecture. I'm also planning on open-sourcing the code once I get it wrapped/cleaned up.

Using the Azure Automation Graphical Authoring SDK is the only supported way of inspecting and modifying the content of .graphrunbok files. For example, a script like this will give you a list of commands used by the runbook:
param(
[Parameter(Mandatory = $true)]
$RunbookPath,
$GraphicalAuthoringSDKPath = 'C:\Program Files (x86)\Microsoft Azure Automation Graphical Authoring SDK'
)
function Get-RunbookActivities($Runbook, $ActivityType)
{
$Runbook.Activities | %{ $_ -as $ActivityType } | ?{ $_ }
}
Add-Type -Path $GraphicalAuthoringSDKPath\Orchestrator.GraphRunbook.Model.dll
$SerializedRunbook = Get-Content $RunbookPath
$Runbook = [Orchestrator.GraphRunbook.Model.Serialization.RunbookSerializer]::Deserialize($SerializedRunbook)
#{
'Invoked runbooks' = Get-RunbookActivities $Runbook Orchestrator.GraphRunbook.Model.InvokeRunbookActivity |
%{ $_.RunbookActivityType.CommandName }
'Commands' = Get-RunbookActivities $Runbook Orchestrator.GraphRunbook.Model.CommandActivity |
%{ "$($_.CommandType.ModuleName)/$($_.CommandType.CommandName)" }
'Code activity content' = Get-RunbookActivities $Runbook Orchestrator.GraphRunbook.Model.WorkflowScriptActivity |
%{ $_.Process }
}
The data provided by this script is incomplete: it lists only activities shown as boxes on the runbook diagram. However, there are other ways to introduce PS code into runbooks (such as link conditions, retry conditions, PS expressions in activity parameters, etc.) If you are interested in this data as well, the script can be improved: all the data stored in a graphical runbook can be retrieved using this API.
Please download the latest version of the SDK from the link provided by Chris. The latest version contains some important fixes.

Use the Azure Automation Graphical Authoring SDK.
https://azure.microsoft.com/en-us/updates/public-preview-automation-graphical-authoring-sdk/

Related

store Windows PowerShell output as a table in Azure SQL DB

I use the below Windows PowerShell script to extract all members of particular Yammer group and store the output as .csv file on my local machine.
What I need is to save this output as a table in Azure SQL DB. What would be the right way to approach this:
Amend the below script to save data in Azure Table?
Use some Azure SQL functionality?
Anything else?
I would appreciate your help,
$GroupId=xxxxx
$Token = "xxxx"
$Headers = #{ "Authorization" = "Bearer "+$Token }
$GroupCycle = 1
DO
{
$GetMoreGroupsUri = "https://www.yammer.com/api/v1/users/in_group/$GroupId.xml?page=$GroupCycle"
write-host ("REST API CALL : $GetMoreGroupsUri")
[xml]$Xml = ((Invoke-WebRequest -Uri $GetMoreGroupsUri -Method Get -Headers $Headers).content)
$YammerGroups += $Xml.response.users.user
$GroupCycle ++
$GroupCount += $Xml.response.users.user.count
write-host ("GROUPMEMBER COUNT : $GroupCount")
}
While ($Xml.response.users.user.count -gt 0)
$YammerGroups | Where {$_} | Export-Csv "$GroupId.csv" -Delimiter ","
I would approach this problem slightly differently. I would use Azure to store the value of the variables I needed and keep the script somewhere else that is cloud accessible, Sharepoint comes to mind, so does GIT.
Here is the documentation on the Azure DB PowerShell Module AzTable:
https://learn.microsoft.com/en-us/azure/storage/tables/table-storage-how-to-use-powershell
Here are a couple of highlights:
#Install Module
Install-Module AzTable
#Get Table Contents
Get-AzStorageTable –Context $ctx | select Name
The Module is very well defined. I encourage you to take a look at all of the different calls listed in the Microsoft Doc.
Here is a breakdown:
Use Sharepoint or Git to store your script
If you want to store values, Azure DB is great. Use the PowerShell Module AzTable to interact with it. You can write and read tables as you see fit.
If you need dynamic variables, simply adjust the code to read the table value and variablize it. Should be easy to accomplish in some of the loops.

Get installed software product context using powershell

I can easily get all installed software products on a machine using
Get-WmiObject -Class Win32_Product
Now I'd like to also fetch the Product Context. How can I access this information for every installed product using PowerShell.
In VB I did that by using the WindowsInstaller COM-Object and then querying the information. In essence this:
Set Com = CreateObject('WindowsInstaller.Installer')
Set Products = Com.ProductsEx(vbNullString,"S-1-1-0",7)
For Each P in Products
context = P.Context
Which I dont not manage to replicate in PowerShell
I realize this question is a bit stale, but I disagree with what seems to be the prevailing notion that working with Windows Installer in PowerShell is somehow a "pain" and more complicated than working with it in VBScript (this post is just one of many).
I have found that VBScript Windows Installer code translates quite literally to PowerShell, which means there are numerous examples of VBScript Windows Installer scripts that can be adapted to PowerShell and used to learn how to work with Windows Installer in PowerShell.
For this specific question of install context, the PowerShell code is quite similar to the VB code the OP gave.
# code must be run with admin rights to use "S-1-1-0" SID
enum InstallContext {
FirstVisible = 0 # product visible to the current user
None = 0 # Invalid context for a product
UserManaged = 1 # user managed install context
UserUnmanaged = 2 # user non-managed context
Machine = 4 # per-machine context
All = 7 # All contexts. OR of all valid values
AllUserManaged = 8 # all user-managed contexts
}
$Installer = New-Object -ComObject WindowsInstaller.Installer
foreach ($P in $Installer.ProductsEx("", "S-1-1-0", 7)) {
[InstallContext]$P.Context()
}
NOTE: I used Enums (about Enum - PowerShell | Microsoft Docs) with PowerShell here since tagMSIINSTALLCONTEXT is an enum in the msi.h file.
It's a pain to use that com object in powershell. I would use vbscript instead and save the text output to a powershell variable, or find an msi powershell module. That com object doesn't have a "type library" or support "IDispatch". The Windows Powershell in Action appendix for 2nd edition goes into it, but even there it's not pretty. That vbscript code has errors.

Use PowerShell to destroy source code marked for deletion in TFS, is this possible?

Example
If you look at the picture, I have marked some sample files/source in VS2017 source Control Explorer as deleted, but TFS doesn't delete it automatically, you have to destroy it manually with the tf destroy command.
I wanted to make PowerShell use the TFS REST API to get source that has been marked for deletion, but looking through their API reference, I haven't found a way to do this, it doesn't seem like the API exposes that kind of information, but somehow Visual Studio 2017 is able to get it, so surely I should be able to?
I'm using TFS2017 Update 2, so this is api version 3.2.
Why I want to do this: We're running low on space and we have lots of team project collections with source marked for deletion. It would be very tedious to destroy everything manually.
If you have TFS Power Tools you can use this PowerShell script to destory all the deleted items (with tf and not with rest api, but it does the work, you don't need to do it manually):
$tfsServer = Get-TfsServer -name http://YOURTFSSERVER:PORT
$destroyList = get-tfschilditem -item $/Root/ -server $tfsServer -Deleted -recurse | Where {$_.DeletionId -ne 0}
foreach($item in $destroyList)
{
$itemPath = '"' + $item.ServerItem + ";X" + $item.DeletionId + '"'
tf destroy $itemPath /i /startcleanup
}
There are no REST APIs for this. You will have to use tf.exe.

How do I get a VM Image from Azure in Powershell?

Previously in Powershell I was using the Get-AzureVMImage cmd-let to retrieve a VM Image I had generated. I would store the image an as object to build a VM with New-AzureQuickVM. Below is a code snippet:
$image = Get-AzureVMImage | where { $_.Imagename -like $basicImageNames[$n] } | Sort-Object -Descending -Property PublishedDate | Select-Object -First 1 -OutVariable image
Now with the new AzureRM Powershell Module, the majority of the cmd-lets for Powershell management have been renamed or deprecated. Get-AzureVMImage.
I've attempted to use Get-AzureRmImage, but it doesn't list any of my VM Images.
I've also attempted to use Get-AzureRmVMImage, but this appears to be valid only for official published images, and not my user generated ones.
Does anyone know of an equivalent cmd-let to the deprecated Get-AzureVMImage?
According to your describe, I think you have created a Classic Image ,right?
As I known, Classic image can only be used to create classic VM. Also, you cannot using Azure RM powershell to get a Classic Image and to create a classic VM.
So, I suggest you can go to Azure portal > VM images(classic)> find your generated Image>Create VM . Or you can also use Azure SM powershell to login your Azure Classic Account and then use Get-Azure VM image.
See more details about Get-AzureVMImage in this document.
See more details about Get-AzureRmImage in this document.

How do I get a list of all tfs alert subscriptions via powershell (get .Net assembly via PowerShell?)

I'm trying to move my tools to powershell, can this be done in PowerShell? the bit I'm really interested in is:
IEventService es = tfs.GetService(typeof(IEventService)) as IEventService;
List<Subscription> ls = es.GetAllEventSubscriptions().ToList();
Edit: what I really want to do might be using a .NET assembly from powershell and this might then be a duplicate of Using .NET library from PowerShell
Here is a TFS API in PowerShell function that I found on a blog long ago that will get you started. I've posted it to a GitHub Gist. Basically you ensure you've loaded up the TFS assemblies into the AppDomain and then you can add any TFS Service Interfaces you want to the object and just operate on them just as you would in any c# application, etc.
https://gist.github.com/3288447
Once you have the TFS object returned from the method in the Gist above, you can operate on the loaded services like so:
#use work item service
$tfs = get-tfs $env:TFSSERVERURL -silent
$project = $tfs.wit.Projects | ?{ $_.Name -eq $projectName}
#todo - replace with text for query or file read -- this is deprecated
$query = $project.StoredQueries | ?{ $_.Name -eq 'Active Bugs' }
$queryText = $query.QueryText.Replace("#project","'$projectName'")
$results = $tfs.wit.Query($queryText)
#do something with the results...
In your request above you can just alter the get-tfs method to add your service interface to the set loaded and then operate on the .NET methods much like I do in the example above.