1212// limitations under the License.
1313// ----------------------------------------------------------------------------------
1414
15- using System . Collections . Concurrent ;
1615using Microsoft . Azure . Common . Authentication ;
1716using Microsoft . Azure . Common . Authentication . Models ;
1817using Microsoft . IdentityModel . Clients . ActiveDirectory ;
1918using Microsoft . WindowsAzure . Commands . Common ;
2019using Microsoft . WindowsAzure . Commands . Common . Properties ;
20+ using Newtonsoft . Json ;
2121using System ;
22+ using System . Collections . Concurrent ;
2223using System . Diagnostics ;
2324using System . IO ;
2425using System . Management . Automation ;
26+ using System . Management . Automation . Host ;
27+ using System . Threading ;
2528
2629namespace Microsoft . WindowsAzure . Commands . Utilities . Common
2730{
@@ -31,6 +34,7 @@ public abstract class AzurePSCmdlet : PSCmdlet
3134 private RecordingTracingInterceptor _httpTracingInterceptor ;
3235 private DebugStreamTraceListener _adalListener ;
3336 protected static AzureProfile _currentProfile = null ;
37+ protected static AzurePSDataCollectionProfile _dataCollectionProfile = null ;
3438
3539 [ Parameter ( Mandatory = false , HelpMessage = "In-memory profile." ) ]
3640 public AzureProfile Profile { get ; set ; }
@@ -147,12 +151,161 @@ protected static void SetTokenCacheForProfile(AzureProfile profile)
147151 }
148152 }
149153
154+ /// <summary>
155+ /// Initialize the data collection profile
156+ /// </summary>
157+ protected static void InitializeDataCollectionProfile ( )
158+ {
159+ if ( _dataCollectionProfile != null && _dataCollectionProfile . EnableAzureDataCollection . HasValue )
160+ {
161+ return ;
162+ }
163+
164+ // Get the value of the environment variable for Azure PS data collection setting.
165+ string value = Environment . GetEnvironmentVariable ( AzurePSDataCollectionProfile . EnvironmentVariableName ) ;
166+ if ( ! string . IsNullOrWhiteSpace ( value ) )
167+ {
168+ if ( string . Equals ( value , bool . FalseString , StringComparison . OrdinalIgnoreCase ) )
169+ {
170+ // Disable data collection only if it is explictly set to 'false'.
171+ _dataCollectionProfile = new AzurePSDataCollectionProfile ( true ) ;
172+ }
173+ else if ( string . Equals ( value , bool . TrueString , StringComparison . OrdinalIgnoreCase ) )
174+ {
175+ // Enable data collection only if it is explictly set to 'true'.
176+ _dataCollectionProfile = new AzurePSDataCollectionProfile ( false ) ;
177+ }
178+ }
179+
180+ // If the environment value is null or empty, or not correctly set, try to read the setting from default file location.
181+ if ( _dataCollectionProfile == null )
182+ {
183+ string fileFullPath = Path . Combine ( AzureSession . ProfileDirectory , AzurePSDataCollectionProfile . DefaultFileName ) ;
184+ if ( File . Exists ( fileFullPath ) )
185+ {
186+ string contents = File . ReadAllText ( fileFullPath ) ;
187+ _dataCollectionProfile = JsonConvert . DeserializeObject < AzurePSDataCollectionProfile > ( contents ) ;
188+ }
189+ }
190+
191+ // If the environment variable or file content is not set, create a new profile object.
192+ if ( _dataCollectionProfile == null )
193+ {
194+ _dataCollectionProfile = new AzurePSDataCollectionProfile ( ) ;
195+ }
196+ }
197+
198+ /// <summary>
199+ /// Get the data collection profile
200+ /// </summary>
201+ protected static AzurePSDataCollectionProfile GetDataCollectionProfile ( )
202+ {
203+ if ( _dataCollectionProfile == null )
204+ {
205+ InitializeDataCollectionProfile ( ) ;
206+ }
207+
208+ return _dataCollectionProfile ;
209+ }
210+
211+ /// <summary>
212+ /// Save the current data collection profile Json data into the default file path
213+ /// </summary>
214+ /// <param name="profile"></param>
215+ protected void SaveDataCollectionProfile ( )
216+ {
217+ if ( _dataCollectionProfile == null )
218+ {
219+ InitializeDataCollectionProfile ( ) ;
220+ }
221+
222+ string fileFullPath = Path . Combine ( AzureSession . ProfileDirectory , AzurePSDataCollectionProfile . DefaultFileName ) ;
223+ var contents = JsonConvert . SerializeObject ( _dataCollectionProfile ) ;
224+ AzureSession . DataStore . WriteFile ( fileFullPath , contents ) ;
225+ WriteWarning ( string . Format ( Resources . DataCollectionSaveFileInformation , fileFullPath ) ) ;
226+ }
227+
228+ protected bool CheckIfInteractive ( )
229+ {
230+ if ( this . Host == null || this . Host . UI == null || this . Host . UI . RawUI == null )
231+ {
232+ return false ;
233+ }
234+
235+ bool interactive = true ;
236+ try
237+ {
238+ var test = this . Host . UI . RawUI . KeyAvailable ;
239+ }
240+ catch ( HostException ex )
241+ {
242+ if ( ex . Message . StartsWith ( "A command that prompts the user failed" ) )
243+ {
244+ interactive = false ;
245+ }
246+ else
247+ {
248+ throw ex ;
249+ }
250+ }
251+
252+ return interactive ;
253+ }
254+
255+ /// <summary>
256+ /// Prompt for the current data collection profile
257+ /// </summary>
258+ /// <param name="profile"></param>
259+ protected void PromptForDataCollectionProfileIfNotExists ( )
260+ {
261+ // Initialize it from the environment variable or profile file.
262+ InitializeDataCollectionProfile ( ) ;
263+
264+ if ( CheckIfInteractive ( ) && ! _dataCollectionProfile . EnableAzureDataCollection . HasValue )
265+ {
266+ WriteWarning ( Resources . DataCollectionPrompt ) ;
267+
268+ const double timeToWaitInSeconds = 60 ;
269+ var status = string . Format ( Resources . DataCollectionConfirmTime , timeToWaitInSeconds ) ;
270+ ProgressRecord record = new ProgressRecord ( 0 , Resources . DataCollectionActivity , status ) ;
271+
272+ var startTime = DateTime . Now ;
273+ var endTime = DateTime . Now ;
274+ double elapsedSeconds = 0 ;
275+
276+ while ( ! this . Host . UI . RawUI . KeyAvailable && elapsedSeconds < timeToWaitInSeconds )
277+ {
278+ Thread . Sleep ( TimeSpan . FromMilliseconds ( 10 ) ) ;
279+ endTime = DateTime . Now ;
280+
281+ elapsedSeconds = ( endTime - startTime ) . TotalSeconds ;
282+ record . PercentComplete = ( ( int ) elapsedSeconds * 100 / ( int ) timeToWaitInSeconds ) ;
283+ WriteProgress ( record ) ;
284+ }
285+
286+ bool enabled = false ;
287+ if ( this . Host . UI . RawUI . KeyAvailable )
288+ {
289+ KeyInfo keyInfo = this . Host . UI . RawUI . ReadKey ( ReadKeyOptions . NoEcho | ReadKeyOptions . AllowCtrlC | ReadKeyOptions . IncludeKeyDown ) ;
290+ enabled = ( keyInfo . Character == 'Y' || keyInfo . Character == 'y' ) ;
291+ }
292+
293+ _dataCollectionProfile . EnableAzureDataCollection = enabled ;
294+
295+ WriteWarning ( enabled ? Resources . DataCollectionConfirmYes : Resources . DataCollectionConfirmNo ) ;
296+
297+ SaveDataCollectionProfile ( ) ;
298+ }
299+ }
300+
150301 /// <summary>
151302 /// Cmdlet begin process. Write to logs, setup Http Tracing and initialize profile
152303 /// </summary>
153304 protected override void BeginProcessing ( )
154305 {
155306 InitializeProfile ( ) ;
307+ PromptForDataCollectionProfileIfNotExists ( ) ;
308+
156309 if ( string . IsNullOrEmpty ( ParameterSetName ) )
157310 {
158311 WriteDebugWithTimestamp ( string . Format ( Resources . BeginProcessingWithoutParameterSetLog , this . GetType ( ) . Name ) ) ;
0 commit comments