Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/AzurePowershell.sln
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.30723.0
VisualStudioVersion = 12.0.40629.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8531411A-0137-4E27-9C5E-49E07C245048}"
ProjectSection(SolutionItems) = preProject
Expand Down Expand Up @@ -632,4 +632,7 @@ Global
{678AE95D-2364-47D7-888C-3FFA6D412CC8} = {95C16AED-FD57-42A0-86C3-2CF4300A4817}
{6C7D3D81-37AB-445E-8081-78A1FEC0A773} = {95C16AED-FD57-42A0-86C3-2CF4300A4817}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EnterpriseLibraryConfigurationToolBinariesPathV6 = packages\EnterpriseLibrary.TransientFaultHandling.6.0.1304.0\lib\portable-net45+win+wp8;packages\EnterpriseLibrary.TransientFaultHandling.Data.6.0.1304.1\lib\NET45
EndGlobalSection
EndGlobal
155 changes: 154 additions & 1 deletion src/Common/Commands.Common/AzurePSCmdlet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,19 @@
// limitations under the License.
// ----------------------------------------------------------------------------------

using System.Collections.Concurrent;
using Microsoft.Azure.Common.Authentication;
using Microsoft.Azure.Common.Authentication.Models;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Microsoft.WindowsAzure.Commands.Common;
using Microsoft.WindowsAzure.Commands.Common.Properties;
using Newtonsoft.Json;
using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.IO;
using System.Management.Automation;
using System.Management.Automation.Host;
using System.Threading;

namespace Microsoft.WindowsAzure.Commands.Utilities.Common
{
Expand All @@ -31,6 +34,7 @@ public abstract class AzurePSCmdlet : PSCmdlet
private RecordingTracingInterceptor _httpTracingInterceptor;
private DebugStreamTraceListener _adalListener;
protected static AzureProfile _currentProfile = null;
protected static AzurePSDataCollectionProfile _dataCollectionProfile = null;

[Parameter(Mandatory = false, HelpMessage = "In-memory profile.")]
public AzureProfile Profile { get; set; }
Expand Down Expand Up @@ -147,12 +151,161 @@ protected static void SetTokenCacheForProfile(AzureProfile profile)
}
}

/// <summary>
/// Initialize the data collection profile
/// </summary>
protected static void InitializeDataCollectionProfile()
{
if (_dataCollectionProfile != null && _dataCollectionProfile.EnableAzureDataCollection.HasValue)
{
return;
}

// Get the value of the environment variable for Azure PS data collection setting.
string value = Environment.GetEnvironmentVariable(AzurePSDataCollectionProfile.EnvironmentVariableName);
if (!string.IsNullOrWhiteSpace(value))
{
if (string.Equals(value, bool.FalseString, StringComparison.OrdinalIgnoreCase))
{
// Disable data collection only if it is explictly set to 'false'.
_dataCollectionProfile = new AzurePSDataCollectionProfile(true);
}
else if (string.Equals(value, bool.TrueString, StringComparison.OrdinalIgnoreCase))
{
// Enable data collection only if it is explictly set to 'true'.
_dataCollectionProfile = new AzurePSDataCollectionProfile(false);
}
}

// If the environment value is null or empty, or not correctly set, try to read the setting from default file location.
if (_dataCollectionProfile == null)
{
string fileFullPath = Path.Combine(AzureSession.ProfileDirectory, AzurePSDataCollectionProfile.DefaultFileName);
if (File.Exists(fileFullPath))
{
string contents = File.ReadAllText(fileFullPath);
_dataCollectionProfile = JsonConvert.DeserializeObject<AzurePSDataCollectionProfile>(contents);
}
}

// If the environment variable or file content is not set, create a new profile object.
if (_dataCollectionProfile == null)
{
_dataCollectionProfile = new AzurePSDataCollectionProfile();
}
}

/// <summary>
/// Get the data collection profile
/// </summary>
protected static AzurePSDataCollectionProfile GetDataCollectionProfile()
{
if (_dataCollectionProfile == null)
{
InitializeDataCollectionProfile();
}

return _dataCollectionProfile;
}

/// <summary>
/// Save the current data collection profile Json data into the default file path
/// </summary>
/// <param name="profile"></param>
protected void SaveDataCollectionProfile()
{
if (_dataCollectionProfile == null)
{
InitializeDataCollectionProfile();
}

string fileFullPath = Path.Combine(AzureSession.ProfileDirectory, AzurePSDataCollectionProfile.DefaultFileName);
var contents = JsonConvert.SerializeObject(_dataCollectionProfile);
AzureSession.DataStore.WriteFile(fileFullPath, contents);
WriteWarning(string.Format(Resources.DataCollectionSaveFileInformation, fileFullPath));
}

protected bool CheckIfInteractive()
{
if (this.Host == null || this.Host.UI == null || this.Host.UI.RawUI == null)
{
return false;
}

bool interactive = true;
try
{
var test = this.Host.UI.RawUI.KeyAvailable;
}
catch (HostException ex)
{
if (ex.Message.StartsWith("A command that prompts the user failed"))
{
interactive = false;
}
else
{
throw ex;
}
}

return interactive;
}

/// <summary>
/// Prompt for the current data collection profile
/// </summary>
/// <param name="profile"></param>
protected void PromptForDataCollectionProfileIfNotExists()
{
// Initialize it from the environment variable or profile file.
InitializeDataCollectionProfile();

if (CheckIfInteractive() && !_dataCollectionProfile.EnableAzureDataCollection.HasValue)
{
WriteWarning(Resources.DataCollectionPrompt);

const double timeToWaitInSeconds = 60;
var status = string.Format(Resources.DataCollectionConfirmTime, timeToWaitInSeconds);
ProgressRecord record = new ProgressRecord(0, Resources.DataCollectionActivity, status);

var startTime = DateTime.Now;
var endTime = DateTime.Now;
double elapsedSeconds = 0;

while (!this.Host.UI.RawUI.KeyAvailable && elapsedSeconds < timeToWaitInSeconds)
{
Thread.Sleep(TimeSpan.FromMilliseconds(10));
endTime = DateTime.Now;

elapsedSeconds = (endTime - startTime).TotalSeconds;
record.PercentComplete = ((int)elapsedSeconds * 100 / (int)timeToWaitInSeconds);
WriteProgress(record);
}

bool enabled = false;
if (this.Host.UI.RawUI.KeyAvailable)
{
KeyInfo keyInfo = this.Host.UI.RawUI.ReadKey(ReadKeyOptions.NoEcho | ReadKeyOptions.AllowCtrlC | ReadKeyOptions.IncludeKeyDown);
enabled = (keyInfo.Character == 'Y' || keyInfo.Character == 'y');
}

_dataCollectionProfile.EnableAzureDataCollection = enabled;

WriteWarning(enabled ? Resources.DataCollectionConfirmYes : Resources.DataCollectionConfirmNo);

SaveDataCollectionProfile();
}
}

/// <summary>
/// Cmdlet begin process. Write to logs, setup Http Tracing and initialize profile
/// </summary>
protected override void BeginProcessing()
{
InitializeProfile();
PromptForDataCollectionProfileIfNotExists();

if (string.IsNullOrEmpty(ParameterSetName))
{
WriteDebugWithTimestamp(string.Format(Resources.BeginProcessingWithoutParameterSetLog, this.GetType().Name));
Expand Down
39 changes: 39 additions & 0 deletions src/Common/Commands.Common/AzurePSDataCollectionProfile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// ----------------------------------------------------------------------------------
//
// Copyright Microsoft Corporation
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------------------------------------------------------------

using System;
using System.IO;
using Newtonsoft.Json;
using Microsoft.Azure.Common.Authentication;

namespace Microsoft.WindowsAzure.Commands.Common
{
public class AzurePSDataCollectionProfile
{
public const string EnvironmentVariableName = "Azure_PS_Data_Collection";
public static string DefaultFileName = "AzureDataCollectionProfile.json";

public AzurePSDataCollectionProfile()
{
}

public AzurePSDataCollectionProfile(bool enable)
{
EnableAzureDataCollection = enable;
}

[JsonProperty(PropertyName = "enableAzureDataCollection")]
public bool? EnableAzureDataCollection { get; set; }
}
}
1 change: 1 addition & 0 deletions src/Common/Commands.Common/Commands.Common.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="AzurePSDataCollectionProfile.cs" />
<Compile Include="AzurePowerShell.cs" />
<Compile Include="ComputeCloudException.cs" />
<Compile Include="Constants.cs" />
Expand Down
59 changes: 58 additions & 1 deletion src/Common/Commands.Common/Properties/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 28 additions & 0 deletions src/Common/Commands.Common/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1468,4 +1468,32 @@ The file needs to be a PowerShell script (.ps1 or .psm1).</value>
<data name="CannotChangeBuiltinEnvironment" xml:space="preserve">
<value>Cannot change built-in environment {0}.</value>
</data>
<data name="DataCollectionPrompt" xml:space="preserve">
<value>Microsoft Azure PowerShell collects data about how users use PowerShell cmdlets and some problems they encounter. Microsoft uses this information to improve our PowerShell cmdlets. Participation is voluntary and when you choose to participate your device automatically sends information to Microsoft about how you use Azure PowerShell.

If you choose to participate, you can stop at any time by using Azure PowerShell as follows:
1. Use the Disable-AzureDataCollection cmdlet to turn the feature Off. The cmdlet can be found in the AzureResourceManager module
To disable data collection: PS &gt; Disable-AzureDataCollection

If you choose to not participate, you can enable at any time by using Azure PowerShell as follows:
1. Use the Enable-AzureDataCollection cmdlet to turn the feature On. The cmdlet can be found in the AzureResourceManager module
To enable data collection: PS &gt; Enable-AzureDataCollection

Select Y to enable data collection [Y/N]:</value>
</data>
<data name="DataCollectionActivity" xml:space="preserve">
<value>Microsoft Azure PowerShell Data Collection Confirmation</value>
</data>
<data name="DataCollectionConfirmNo" xml:space="preserve">
<value>You choose not to participate in Microsoft Azure PowerShell data collection.</value>
</data>
<data name="DataCollectionConfirmTime" xml:space="preserve">
<value>This confirmation message will be dismissed in '{0}' second(s)...</value>
</data>
<data name="DataCollectionConfirmYes" xml:space="preserve">
<value>You choose to participate in Microsoft Azure PowerShell data collection.</value>
</data>
<data name="DataCollectionSaveFileInformation" xml:space="preserve">
<value>The setting profile has been saved to the following path '{0}'.</value>
</data>
</root>
2 changes: 2 additions & 0 deletions src/Common/Commands.Profile/Commands.Profile.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@
<Compile Include="Models\PSAzureEnvironment.cs" />
<Compile Include="Models\PSAzureSubscription.cs" />
<Compile Include="Models\PSAzureSubscriptionExtended.cs" />
<Compile Include="DataCollection\EnableAzureDataCollection.cs" />
<Compile Include="DataCollection\DisableAzureDataCollection.cs" />
<Compile Include="Profile\SelectAzureProfile.cs" />
<Compile Include="Profile\NewAzureProfile.cs" />
<Compile Include="Profile\ClearAzureProfile.cs" />
Expand Down
Loading