How can I pack a configuration archive without logging in? I want to run this command in an automation context:
Publish-AzureRmVMDscConfiguration -Force -ConfigurationPath .\AppServer.ps1 -ConfigurationArchivePath .\AppServer.ps1.zip
There are no calls out to the network, I'm not performing any subscription operations that require authorization, I just want it to make me a nice zip file with the cmdlet. However, when I try, it fails:
Publish-AzureRmVMDscConfiguration : Run Login-AzureRmAccount to login.
This seems silly to me but I went ahead and checked Get-Help. I can't find anything that looks helpful though. How can I pack up my DSC configuration without having to run Login-AzureRmAccount?
I suspect this is a "design limitation" - you might start by filing an issue here: https://github.com/Azure/azure-powershell
As a workaround, depending on the "sophistication" of your DSC config, you can just create a zip file yourself. If you have additional/non-default modules or resources, you'd need to put those in the archive as well (which is what the cmdlet helps with)...
Related
I have a .bat file that starts up a powershell script.
Within this powershell script, i startup PowerBI with a given database.
The powershell script waits till powerBI has been done starting up, and will then be exporting data to some datadump files.
Doing this manually works fine, and also when its on the task scheduler to run when user is logged on.
The moment i change this to "Run whether user is logged on or not" it doesnt work anymore.
The reason behind this, is that it seems that powershell is unable to start PowerBI and therefore there is no open data to query in the rest of the script.
So the positive side is it runs the bat and powershell just fine, only the powershell itself seems incapable to start powerBI.
Are there any solutions to this? should i for example use a different method to call the appliation to start?
currently the powershell snippit to start the app looks like this:
$PBIDesktop = "C:\Program Files\Microsoft Power BI Desktop\bin\PBIDesktop.exe"
$template = "C:\LiveData\Data.pbix"
$waitoPBD = 60
$app = START-PROCESS $PBIDesktop $template -PassThru
log_message "Waiting $($waitoPBD) seconds for PBI to launch"
Start-Sleep -s $waitoPBD
I faced similar issue. So, sharing my experience..
First of all, please verify couple of things.
Specify user account which will be used to invoke the job. Also, ensure that, the account have sufficient permission.
Don't forget to un-check the checkbox (as shown in screenshot) under Conditions Tab
Just found this one - sorry it took so long :D
But, i had this totally nervwrecking issue to.
Solution for me is to realize that the task scheduler is very deep part of the OS.
Thats why i have to grant access to the file, for the computername$ (system name) on the file or folder containing the file to run.
Rightclick on the file or folder -> Security. Select edit and add [Name of your computer]$ and give the read and execute permissions.
That's the only way I can make it run.
But i hope you found the solution in the meantime :)
How can I run a powershell script after all stages have completed deployment? I have currently selected a deployment group job but am not 100% sure if this is what I need. I have included the script as part of the solution that is being deployed so that it will be available on all machines. Based on what I can find in the UI there seem to be 2 tasks that could work.
The first option would be to execute the task "Powershell Script" but it is asking for a path in the drop directory. The problem with this is that the file that I am interested in is in a zip file and there does not seem to be a way to specify a file in the zip file.
The other task I see is "PowerShell on Target Machines" and then it asks for a list of target machines. I am not sure what needs to be entered here as I want to run the powershell script on the current machine in the deploy group. It seems like this task was intended to run powershell scripts from the deployment machine to another remote machine. As a result this option does not seem like it fits my use case.
From looking the answers that I have come across talk about how to do this as part of an Azure site using something called "Kudu" (not relevant) or don't answer my other questions related to these tasks or seem like they are out of date.
A deployment group job will run on all of the servers specified in that deployment group. Based on what you have indicated, it sounds like that is what you are looking for.
Since you indicated that the file in question is a zip, you are actually going to need to use 2 separate tasks.
Extract Files - use this to extract the zip file so that you can execute the script
Powershell script - use this to execute the script. You can set the working directory for the script to execute in if necessary (under advanced options). Also remember that you don't have to use the file/folder selector 'helper' as it wont work in your case if the file is inside a zip. This is just used to populate the text box which you can manually do starting with the $(System.DefaultWorkingDirectory) variable and adding the necessary path of the script.
I have created a custom module as a PowerShell class following, roughly, the instructions available at Writing a custom DSC resource with PowerShell classes. The intent is to connect to Azure File Storage and download some files. I am using Azure Automation DSC as my pull server.
Let me start by saying that, when run through the PowerShell ISE, the code works a treat. Something goes wrong when I upload it to Azure though - I get the error Unable to find type [CloudFileDirectory]. This type specifier comes from assemblies referenced in through the module Azure.Storage which is definitely in my list of automation assets.
At the tippy top of my psm1 file I have
Using namespace Microsoft.WindowsAzure.Storage.File
[DscResource()]
class tAzureStorageFileSync
{
...
# Create the search context
[CloudFileDirectory] GetBlobRoot()
{
...
}
...
}
I'm not sure whether this Using is supported in this scenario or not, so let's call that Question 1
To date I have tried:
Adding RequiredModules = #( "Azure.Storage" ) to the psd1 file
Adding RequiredAssemblies = #( "Microsoft.WindowsAzure.Storage.dll" ) to the psd1 file
Shipping the actual Microsoft.WindowsAzure.Storage.dll file in the root of the module zip that I upload (that has a terrible smell about it)
When I deploy the module to Azure with New-AzureRmAutomationModule it uploads and processes just fine. The Extracting activities... step works and gives no errors.
When I compile a configuration, however, the compilation process fails with the Unable to find type error I mentioned.
I have contemplated adding an Import-Module Azure.Storage above the class declaration, but I've never seen that done anywhere else before.
Question 2 Is there a way I can compile locally using a similar process to the one used by Azure DSC so I can test changes more quickly?
Question 3 Does anyone know what is going wrong here?
Question 1/3:
If you create classes in powershell and use other classes within, ensure that these classes are present BEFORE loading the scriptfile that contains your new class.
I.e.:
Loader.ps1:
Import-Module Azure.Storage
. .\MyDSC-Class.ps1
Powershell checks if it finds all types you refer while interpreting the script, so all types must be loaded before that happens. You can do this by creating a scriptfile that loads all dependencies first and loads your script after that.
For question 2, if you register your machine as a hybrid worker you'll be able to run the script faster and compile locally. (For more details on hybrid workers, https://azure.microsoft.com/en-us/documentation/articles/automation-hybrid-runbook-worker/).
If you want an easy way to register the hybrid worker, you can run this script on your local machine (https://github.com/azureautomation/runbooks/blob/master/Utility/ARM/New-OnPremiseHybridWorker.ps1). Just make sure you have WMF 5 installed on your machine beforehand.
For authoring DSC configurations and testing locally, I would look at the Azure Automation ISE Add-On available on https://www.powershellgallery.com/packages/AzureAutomationAuthoringToolkit/0.2.3.6 You can install it by running the below command from an Administrator PowerShell ISE window.
Install-Module AzureAutomationAuthoringToolkit -Scope CurrentUser
For loading libraries, I have also noticed that I need to call import-module in order to be able to call methods. I need to do some research to determine the requirement for this. You can see an example I wrote to copy files from Azure Storage using a storage key up on https://github.com/azureautomation/modules/tree/master/cAzureStorage
As you probably don't want to have to deploy the storage library on all nodes, I included the storage library in the sample module above so that it will be automatically distributed to all nodes by the automation service.
Hope this helps,
Eamon
I'm having difficulties trying to setup a startup task in an Azure role.
The ultimate goal is to disable RC4 cipher, along with other SSL configurations. In my (VS2012Express) project (solution partially achieved following another answer here in SO that led me to https://gist.github.com/sidshetye/29d6d48dfa0c2f5488a4 ) I created a Startup.cmd file like this:
# Execute powershell command to disable RC4 and imporve SSL security settings
ECHO Batch started >> "StartupLog.txt" 2>&1
PowerShell -ExecutionPolicy Unrestricted .\HardenSSL.ps1 >> log- HardenSSL.txt 2>&1
EXIT /B 0
HardenSSL.ps1 is the PowerShell script from the previous link. Both the .cmd and .ps1 scripts are placed in the application root directory, marked as "Content" with properties set to "CopyLocal=Always".
In my service definition, I put this:
<Startup>
<Task commandLine="Startup.cmd" executionContext="elevated" taskType="background"></Task>
</Startup>
Now, when I deploy the application to Azure, "nothing" happens. I configured the role instance to allow remote desktop, connected to the machine. I verified the scripts where published, and there were no log files, RC4 still enabled. I tried to manually run the .cmd and the machine runs the scripts to completion, disables RC4 and restarts. So the scripts are actually "correct".
The problem is that the scripts are not getting fired up at startup. I may be wrong, but I don't see anything related looking Windows events. Actually, the server now keeps all the configurations, but I have to be sure the scripts get executed in case I'll have to publish to new instances/cloud services.
I also tried to:
1. place the scripts on a child directory
2. create other 2 "simpler" .cmd that just create a log file with "script started" to exclude problems related to the .cmd calling the PowerShell script.
None of those scripts got executed.
Hope I've been sufficiently clear, any help would be greatly appreciated.
Thank you in advance,
Alberto
UPDATE 1
Reading through various discussions, I missed one very important thing: the script files are actually published in 2 distinct places, one being inside the /bin folder.
Ex: I placed my scripts in a /StartupScripts folder in my project, and when I connect via Remote Desktop to the Azure server I find the scripts both in "approot/StartupScripts" and in "approot/bin/StartupScripts".
The scripts the are actually executing are those placed inside the "bin" folder. the real problem is that I have probably a path problem inside the .cmd since I now found the execution logs with an error.
Now I will try to change it up and update the question here on SO.
Ok.
In the end it was indeed a problem with a path in my Startup.cmd file: .\HardenSSL.ps1 could not be found if the StartUp Task pointed to a subfolder.
Solution was to place both Startup.cmd and HardenSSL.ps1 files in the application root, remove the ".\" part when calling the PowerShell Script and all worked well.
Anyway, I would like to suggest anyone to pick this other solution I found in stack exchage:
https://security.stackexchange.com/a/79957
It links to a NuGet package that does the same thing as the script I found on the link to github in the original post, just "better"; mainly:
Better configuration of cipher suites, with support for ForwardSecrecy for all reference browsers on SSLLabs
Retain SSL support for Internet Explorer 8 on windows XP (unfortunately still a necessity for us)
Alberto.
All,
Note: I have updated the question after some feedback.
Thanks to #jisaak for his help so far.
I have the need to run a PowerShell script that adds TCP bindings and some other stuff when I deploy my Cloud Service.
Here is my Cloud Service Project:
Here is my Cloud Service Project and Webrole project:
Here is my task in ServiceDefinition.csdef:
And here is the PowerShell script I want to run:
here is my attempt at the Startup.cmd:
When I deploy I get this in the Azure log:
And this in the powershell log:
Any help would be very much appreciated.
I think I am nearly there but following other people syntax on the web doesn't seem to get me there.
thanks
Russ
I think the issue is that the working directory of the batch command interpreter when it runs Startup.cmd runs is not as expected.
The Startup.cmd is located in the \approot\bin\Startup directory but the working directory is \approot\bin.
Therefore the command .\RoleStartup.ps1 is not able to find the RoleStartup.ps1 as it is looking in the bin directory not in the bin\Startup directory.
Solutions I know to this are:
Solution 1:
Use ..\Startup\RoleStartup.ps1 to call the RoleStartup.ps1 from Startup.cmd.
Soltuion 2:
Change the current working directory in Startup.cmd so that the relative path .\RoleStartup.ps1 is found. I do this by CHDIR %~dp0 (see here) to change into the directory that contains Startup.cmd.
Solution 3:
As Don Lockhart's answer suggested, do not copy the Startup directory to the output, instead leave it set as "Content" in the Visual Studio project. This means the files within it will exist in the \approot\Startup directory on the Azure instance. (You would then want to make sure that the Startup folder is not publically accessible via IIS!). Then update the reference to Startup.cmd in ServiceDefinition.csdef to ..\Startup\Startup.cmd, and update the reference to RoleStartup.ps1 in Startup.cmd to ..\Startup\RoleStartup.ps1. This works on the fact that the working directory is bin and uses ..\Startup to always locate the Startup directory relative to it.
You don't need to set the executionpolicy within your cmd - just call the script. Also, you should use a relative path because you can't rely that there is C disk.
Change your batch to:
powershell -executionpolicy unrestricted -file .\RoleStartup.ps1
Right click on the RoleStartup.ps1 and Startup.cmdin Visual Studio and ensure that the Copy to Output directory is set to copy always.
If this still doesn't work, remove the startup call in your csdef, deploy the service, rdp into it and try to invoke the script by yourself to retrieve any errors.
Edit:
Try to adopt your script as below:
Import-Module WebAdministration
$site = $null
do # gets the first website until the result is not $null
{
$site = Get-WebSite | select -first 1
Sleep 1
}
until ($site)
# get the appcmd path
$appcmd = Join-Path ([System.Environment]::GetFolderPath('System')) 'inetsrv\appcmd.exe'
# ensure the appcmd.exe is present
if (-not (Test-Path $appcmd))
{
throw "appcmd.exe not found in '$appcmd'"
}
# The rest of your script ....
I've found it easier in the past to not copy the content to the output directory. I have approot\bin as the working directory. My startUp task element's commandLine attribute uses a relative reference to the .cmd file like so:
The .cmd file references the PowerShell script relatively from the working directory as well:
PowerShell -ExecutionPolicy Unrestricted -f ..\StartUp\RoleStartup.ps1
Ok,
So I am coming back to this after many different attempts to make it work.
I have tried using:
Startup config in the ServiceDefinition.csdef
I have tried registering a scheduled task on the server that scans the Windows Azure log looking for [System[Provider[#Name='Windows Azure Runtime 2.6.0.0'] and EventID=10004]]
Nothing worked either due to security or the timing of events and IIS not being fully setup yet.
So I finally bit the bullet and used my Webrole.cs => public override bool OnStart() method:
Combined with this in the ServiceDefinition.csdef:
Now it all works. This was not the most satisfying result as some of the other ways to do it felt more elegant. Also, many others posted that they got the other ways of doing it to work. Maybe I would have got there eventually but my time was restricted.
thanks
Russ