I'm building a C# desktop application that needs to connects to Azure Ressource Manager. The app must be independent from the Azure Portal.
I need to execute two PowerShell scripts file from C# to create an native application in Azure Active Directory.
the first scipt is :
Import-Module AzureRM.profile
Login-AzureRmAccount
The second is :
$pwd = "{service-principal-password}"
$secureStringPassword = ConvertTo-SecureString -String $pwd -AsPlainText -Force
$azureAdApplication = New-AzureRmADApplication `
-DisplayName $appName `
-HomePage $appHomePage `
-IdentifierUris $appIdentifierUris `
-Password $secureStringPassword
New-AzureRmADServicePrincipal -ApplicationId $azureAdApplication.ApplicationId
New-AzureRmRoleAssignment -RoleDefinitionName Reader `
-ServicePrincipalName $azureAdApplication.ApplicationId.Guid
I have two pass $pwd, $appName, $appHomepage from C# code
Am I on the right way ?? need help
You're getting close to it.
However, there are some tips for your scenario:
The scripts you posted are for creating service principal, not the whole steps for integrating your desktop app.
You can use the ApplicationId in that command:New-AzureRmRoleAssignment -RoleDefinitionName Reader -ServicePrincipalName $azureAdApplication.ApplicationId
If you want to use powershell to integrate your app, you can refer to these app creation scripts.
You can also refer to this sample to Integrate Azure AD into a Windows desktop application using interactive authentication.
For demonstrates a Desktop daemon application, you can refer to this sample.
Both samples have the application creation powershell scripts.
Please let me know if this helps!
Related
I need to create an automation of the environment variable replacement process in PowerApps. The environment variable is the model ID that I trained in Azure Form Recognizer. Now I need to transfer the trained module to another Subscription. For this, I wrote a console application and installed it in the repository. Using Azure DevOps, I launch the application and in the console I get a line with the new ModelID. And now I need to write the new ModelID to the Azure DevOps variable.
I am trying to do it like this - Console.WriteLine($"##vso[task.setvariable variable=ModelId;]{modelId}");
But it doesn't work ....
Suggest you to try using in this way as below code:
Console.WriteLine ("##vso[task.setvariable variable= ModelID]" + ModelID);
Pls check whether you can set the ENV Variable using the below:
Write-Host "##vso[task.setvariable variable=ModelID;]<VALUE>"
If this is working for you, you can invoke the above powershell command using your Console App.
I want to run command "Connect-MsolService" on powershell but without the user interaction. It should take Windows authentication. Also i can't save my password in any external text file to do the authentication.
I want it to be authenticated by currently logged in Windows server credential and authenticate.
Is there any possible way to do that in Powershell?
You could try the command as below to login with non-interactive way, make sure the user account is not MFA-enabled.
$azureUsername="user#xxxx.onmicrosoft.com"
$azurePassword = ConvertTo-SecureString "<Password>" -AsPlainText -Force
$psCred = New-Object System.Management.Automation.PSCredential($azureUsername , $azurePassword)
Connect-MsolService -Credential $psCred
so i am building a UWP program where this current module needs to be able to make a network share folder that is available to all users (compatible with windows IOT device as well).
I am aware of using Powershell to do this (currently this is what i'm trying), however i want to make sure this is my best course of action.
Any guidance would be greatly appreciated.
Side note, i am building it in UWP because i wanted to make a gui for the user to build a config file which in the end would be easier for someone to understand.
For those wondering if i did it/looking for an answer.
I ended up going the powershell route (however from what i understand, it could be done in c# as well).
here is some of my sample code
using (var ps = PowerShell.Create())
{
ps.Runspace.SessionStateProxy.SetVariable("Path", #"C:\path-to-folder");
ps.Runspace.SessionStateProxy.SetVariable("FPath", #"C:\path-to-folder\*foldername*");
ps.AddScript("New-Item -Path $Path -Name \"*foldername*\" -ItemType \"directory\" -Force;");
ps.AddScript("New-SmbShare -Name \"*foldername*\" -Path $FPath -FullAccess Everyone");
ps.Invoke();
}
var newProcessInfo = new System.Diagnostics.ProcessStartInfo();
newProcessInfo.FileName = #"C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe";
newProcessInfo.Verb = "runas";
newProcessInfo.Arguments = "net user '*CustomUserName*' '*password*' /add; net localgroup 'Administrators' '*CustomUserName*' /add";
System.Diagnostics.Process.Start(newProcessInfo);
so what this does is add a folder and create the network share. Then it creates a local user to get around the (IIRC) UAC which can be prompted, and then makes it a member of the admin group.
The reason why i'm doing it this way is because i need a remote device to access the network share without asking the user for their account credentials, therefore making it completely hands-off
I am a student and I am currently trying to learn Azure platform and how to use the C# libraries to manage it.
I was able to create, delete blob and files with no problem using the package WindowsAzure.Storage.
Then I wanted to list VMs using this tutorial : https://learn.microsoft.com/en-us/azure/virtual-machines/windows/csharp
This is my code:
var credentials = SdkContext.AzureCredentialsFactory.FromFile(Environment.GetEnvironmentVariable("AZURE_AUTH_LOCATION"));
var azure = Azure
.Configure()
.WithLogLevel(HttpLoggingDelegatingHandler.Level.Basic)
.Authenticate(credentials)
.WithDefaultSubscription();
Console.WriteLine(azure.VirtualMachines.List().Count());
My connection file look like this:
subscription=********-****-****-****-************
client=********-****-****-****-************
key=qeFkWjPm0YHn5xw8UMS2ytLhf9Oi0rEMxZVOTpk3aMQ=
tenant=********-****-****-****-************
managementURI=https://management.core.windows.net/
baseURL=https://management.azure.com/
authURL=https://login.windows.net/
graphURL=https://graph.windows.net/
But I get this error:
Unhandled Exception: Microsoft.Rest.Azure.CloudException: The client '********-****-****-****-************' with object id '********-****-****-****-************' does not have authorization to perform action 'Microsoft.Compute/virtualMachines/read' over scope '/subscriptions/********-****-****-****-************'.
There is two weird things I noticed :
1 - In the exception message, the client id and object id are the same and I dont know where they come from.
2 - When I create a new application registration on AzureAD, I can't see it in "My apps" but only in "All Apps", and I cant add myself as an owner.
Click here to see a screenshot
I have searched for 2 days and I cant figured out why it's not working.
(This is a simple .Net Core 2 console project, I am on Linux if it can help to find out)
Thank you in advance.
Edit #1 :
Thank's to #juunas, working now.
Help link: https://learn.microsoft.com/en-US/azure/azure-resource-manager/resource-group-create-service-principal-portal#assign-application-to-role
To read details about a VM, the application should have a Reader role on the VM, its resource group, or the subscription. If you need to modify things, Contributor allows all modifications. You should add the application to a role via the Access Control IAM tab on the subscription/resource group/resource.
I have the following C# code
using (RunspaceInvoke invoker = new RunspaceInvoke())
{
invoker.Invoke("Set-ExecutionPolicy Unrestricted");
// ...
}
which gives me the exception
Access to the registry key
'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell'
is denied.
According to this, the solution is to start PowerShell as an administrator.
Ordinarily, this can be accomplished by right-clicking PowerShell and selecting "Run as Administrator". Is there a way to do this programmatically?
I know this is an old post, but we ran into this same problem recently.
We had to scope the execution policy on the machine running the C# code by running the following from PowerShell...
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted
When we had done this previously, without scoping, we were setting the execution policy for Administrator. Visual Studio \ C# was running as the current user, causing it to fail with insufficient permissions.
Check this out
You need to impersonate as an administrator to do it (you will of course need administrator credentials)
Check that article, that also comes with code ready to use (I've used it and it works great)
Basically, you need to do this:
using ( new Impersonator( "myUsername", "myDomainname", "myPassword" ) )
{
using (RunspaceInvoke invoker = new RunspaceInvoke())
{
invoker.Invoke("Set-ExecutionPolicy Unrestricted");
}
}
Administrative privileges are at the application level. The app that needs admin access in this case is yours. Creating runspaces in C# in a custom app does not invoke powershell the application - it just loads some assemblies into your application.
That said, you can elevate as the other poster said although embedding admin usernames and passwords into source code make me feel ill.
-Oisin
I think an alternative model would be to wrap the powershell executor into a simple asp.net webapi webservice.
The webservice could then be configured to run with the required permissions needed to do it's job. It can provide it's own security to determine which clients can call it.
To execute a script, you would just call webservice methods. You could make the method quite general - script name and params.
It's a bit more work, but a lot more secure (see x0n's thoughts).
Strictly for DEV environment
This is relatively very old post.
But I have found a new way to do this.
I am hosting the C# web api on IIS 8 having some powershell code that I want to run with administrator privileges.
So I provided the admin credentials in the Application pool identity setting.
Just set administrator account in app pool identity.
Hope this helps to anyone. :)