Skip to content

Commit 595b037

Browse files
author
Melony QIN
authored
Merge pull request #9 from microsoft/master
merge from the master
2 parents a2eb3f8 + a2e053e commit 595b037

10 files changed

Lines changed: 565 additions & 52 deletions

File tree

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
-- TABLES --
2+
/****** Object: Table [dbo].[RealtimeSensorRecord] ******/
3+
SET ANSI_NULLS ON
4+
GO
5+
SET QUOTED_IDENTIFIER ON
6+
GO
7+
CREATE TABLE [dbo].RealtimeSensorRecord(
8+
[RecordId] [uniqueidentifier] NOT NULL,
9+
[TurbineId] [varchar](50) NULL,
10+
[SensorType] [varchar](50) NULL, --
11+
[SensorId] [varchar](50) NULL,
12+
[SensorValue] [real] NULL,
13+
[Timestamp] [datetime] NULL
14+
15+
PRIMARY KEY CLUSTERED
16+
(
17+
[RecordId] ASC
18+
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
19+
) ON [PRIMARY]
20+
GO
21+
22+
-- STORE PROCEDURES --
23+
/* Store procedure that clean up the sensor records table */
24+
CREATE PROCEDURE [dbo].[TruncateRealtimeSensorRecords]
25+
AS
26+
DECLARE @SQL VARCHAR(2000)
27+
SET @SQL='TRUNCATE TABLE dbo.RealtimeSensorRecord'
28+
EXEC (@SQL);
29+
30+
31+
-- Run Model Store Procedure
32+
SET ANSI_NULLS ON
33+
GO
34+
SET QUOTED_IDENTIFIER ON
35+
GO
36+
37+
IF OBJECT_ID ( 'RunModel', 'P' ) IS NOT NULL
38+
DROP PROCEDURE RunModel;
39+
GO
40+
41+
CREATE PROCEDURE [dbo].RunModel
42+
@Result INT = 0 OUTPUT
43+
AS
44+
BEGIN
45+
SET NOCOUNT ON;
46+
47+
DECLARE @model VARBINARY(max) = (
48+
SELECT DATA
49+
FROM dbo.models
50+
WHERE id = 1
51+
)
52+
53+
;WITH predict_input AS (
54+
SELECT WindSpeedStdDev, TurbineSpeedStdDev, OverallWindDirection, TurbineWindDirection,
55+
WindSpeedAverage, WindTempAverage, GearboxOilLevel, GearboxOilTemp, GeneratorActivePower,
56+
GeneratorSpeed, GeneratorTemp, GeneratorTorque, GridFrequency, GridVoltage,
57+
HydraulicOilPressure, NacelleAngle, PitchAngle, Vibration, TurbineSpeedAverage
58+
FROM
59+
(
60+
SELECT SensorValue, SensorType, timestamp
61+
FROM RealtimeSensorRecord
62+
GROUP BY SensorValue, SensorType, timestamp
63+
) d
64+
PIVOT
65+
(
66+
MAX(SensorValue)
67+
FOR SensorType IN (WindSpeedStdDev, TurbineSpeedStdDev, OverallWindDirection, TurbineWindDirection,
68+
WindSpeedAverage, WindTempAverage, GearboxOilLevel, GearboxOilTemp, GeneratorActivePower,
69+
GeneratorSpeed, GeneratorTemp, GeneratorTorque, GridFrequency, GridVoltage,
70+
HydraulicOilPressure, NacelleAngle, PitchAngle, Vibration, TurbineSpeedAverage)
71+
) piv
72+
)
73+
74+
SELECT @Result = p.output_label
75+
FROM PREDICT(MODEL = @model, DATA = predict_input) WITH (output_label bigint) AS p
76+
END
77+
GO
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/* Create users using the logins created */
2+
CREATE USER OperatorUser WITHOUT LOGIN;
3+
CREATE USER DataScientistUser WITHOUT LOGIN;
4+
CREATE USER SecurityUser WITHOUT LOGIN;
5+
CREATE USER TurbineUser WITHOUT LOGIN;
6+
7+
/* Grand permissions to users */
8+
GRANT SELECT ON RealtimeSensorRecord TO OperatorUser;
9+
GRANT SELECT ON RealtimeSensorRecord TO DataScientistUser;
10+
GRANT SELECT ON RealtimeSensorRecord TO SecurityUser;
11+
GRANT SELECT, INSERT ON RealtimeSensorRecord TO TurbineUser;
12+
13+
14+
-- Mask the last four digits of the serial number (Sensor ID) of the sensor for the Data Scientist
15+
ALTER TABLE RealtimeSensorRecord
16+
ALTER COLUMN SensorId varchar(50) MASKED WITH (FUNCTION = 'partial(34,"XXXX",0)');
17+
DENY UNMASK TO DataScientistUser;
18+
GO
19+
20+
/**
21+
* Operator: Can see all events
22+
* Data Scientist: Can see everything BUT Hatch Sensor events
23+
* Security: Can ONLY see HatchSensor events
24+
*/
25+
ALTER TABLE RealtimeSensorRecord
26+
ALTER COLUMN SensorType sysname
27+
GO
28+
29+
CREATE SCHEMA Security;
30+
GO
31+
32+
/**
33+
* Operator: Can see all events
34+
* Data Scientist: Can see everything BUT Hatch Sensor events
35+
* Security: Can ONLY see HatchSensor events
36+
*/
37+
CREATE FUNCTION Security.fn_securitypredicate(@SensorType AS sysname)
38+
RETURNS TABLE
39+
WITH SCHEMABINDING
40+
AS
41+
RETURN SELECT 1 AS fn_securitypredicate_result
42+
WHERE
43+
USER_NAME() = 'OperatorUser' OR USER_NAME() = 'dbo' OR
44+
(USER_NAME() = 'DataScientistUser' AND @SensorType <> 'HatchSensor') OR
45+
(USER_NAME() = 'SecurityUser' AND @SensorType = 'HatchSensor');
46+
47+
CREATE SECURITY POLICY SensorsDataFilter
48+
ADD FILTER PREDICATE Security.fn_securitypredicate(SensorType)
49+
ON dbo.RealtimeSensorRecord
50+
WITH (STATE = ON);
51+
52+
/* QUERIES FOR TESTING POLICIES */
53+
54+
-- Testing basic policy to deny delete
55+
EXECUTE AS USER = 'OperatorUser';
56+
SELECT * FROM RealtimeSensorRecord;
57+
DELETE FROM RealtimeSensorRecord WHERE SensorType = 'GeneratorTorque';
58+
REVERT;
59+
60+
-- Testing the masking for data Data Scientist
61+
EXECUTE AS USER = 'DataScientistUser';
62+
SELECT TOP 10 * FROM RealtimeSensorRecord;
63+
REVERT;
64+
65+
-- Testing Row-Level Security policy with Operator that can see all the events
66+
EXECUTE AS USER = 'OperatorUser';
67+
SELECT * FROM RealtimeSensorRecord;
68+
REVERT;
69+
70+
-- Testing Row-Level Security policy with DataScientist that can see all the events but HatchSensor
71+
EXECUTE AS USER = 'DataScientistUser';
72+
SELECT * FROM RealtimeSensorRecord;
73+
REVERT;
74+
75+
-- Testing Row-Level Security policy with Security that can see only the HatchSensor events
76+
EXECUTE AS USER = 'SecurityUser';
77+
SELECT * FROM RealtimeSensorRecord;
78+
REVERT;
Binary file not shown.

samples/manage/azure-hybrid-benefit/README.md

Lines changed: 58 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ services: Azure SQL
33
platforms: Azure
44
author: anosov1960
55
ms.author: sashan
6-
ms.date: 1/11/2021
6+
ms.date: 2/2/2021
77
---
88

99
# Overview
1010

11-
This script provides a simple solution to analyze and track the consolidated utilization of SQL Server licenses by all of the SQL resources in a specific subscription or the entire the account. By default, the script scans all subscriptions the user account has access. Alternatively, you can specify a single subscription or a .CSV file with a list of subscription. The usage report includes the following information for each scanned subscription.
11+
This script provides a simple solution to analyze and track the consolidated utilization of SQL Server licenses by all of the SQL resources in a specific subscription or the entire account. By default, the script scans all subscriptions the user account has access to. Alternatively, you can specify a single subscription or a .CSV file with a list of subscription. The usage report includes the following information for each scanned subscription.
1212

1313
| **Category** | **Description** |
1414
|:--|:--|
@@ -45,15 +45,14 @@ The following resources are in scope for the license utilization analysis:
4545

4646
The script accepts the following command line parameters:
4747

48-
| **Parameter** &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | **Value** | **Description** |
48+
| **Parameter** &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | **Value** &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; | **Description** |
4949
|:--|:--|:--|
50-
|-SubId|subscription_id *or* a file_name|Accepts a .csv file with the list of subscriptions<sup>1</sup>|
51-
|-UseInRunbook||Must be specified when executed as a Runbook|
52-
|-Server|[protocol:]server[instance_name][,port]|Required to save data to the database|
53-
|-Database|database_name|Required to save data to the database|
54-
|-Username|user_name|Required to save data to the database|
55-
|-Password|password|Required to save data to the database, must be passed as a *[SecureString]* variable|
56-
|-FilePath|csv_file_name|Required to save data in a .csv format. Ignored if database parameters are specified|
50+
|-SubId|subscription_id *or* a file_name|Optional: subscription id or a .csv file with the list of subscriptions<sup>1</sup>|
51+
|-UseInRunbook| \$True or \$False (default) |Optional: must be $True when executed as a Runbook|
52+
|-Server|[protocol:]server[instance_name][,port]|Optional: SQL Server connection endpoint to save data to the database.<br> Must be accompanied by -Database and -Cred |
53+
|-Database|database_name|Optional: database name where data will be saved.<br> Must be accompanied by -Server and -Cred|
54+
|-Cred|credential_object|Optional: value of type PSCredential to securely pass database user and password|
55+
|-FilePath|csv_file_name|Optional: filename where the data will be saved in a .csv format. Ignored if database parameters are specified|
5756

5857
<sup>1</sup>You can create a .csv file using the following command and then edit to remove the subscriptions you don't want to scan.
5958
```PowerShell
@@ -79,39 +78,78 @@ The following command will scan the subscription `<sub_id>` and save the results
7978

8079
## Example 3
8180

82-
The following command will scan all the subscriptions in the account and save the results in a SQL database `<db_name>` on a SQL Server instance `<sql_server_name>.database.windows.net`.
81+
The following command will scan all the subscriptions in the account and save the results in a SQL database `sql-license-usage` on a SQL Server instance `my-westus2-server.database.windows.net`. It will prompt for the database user name and password.
8382

8483
```PowerShell
85-
$cred = Get-Credential -credential <user_name>
86-
.\sql-license-usage.ps1 -Server <server_name>.database.windows.net -Database <db_name> -Username $cred.Username -Password $cred.Password
84+
$cred = Get-Credential
85+
.\sql-license-usage.ps1 -Server my-westus2-server.database.windows.net -Database sql-license-usage -Cred $cred
86+
```
87+
88+
## Example 4
89+
90+
The following command uses the parameter splatting method to achieve the same outcome as Example 3.
91+
92+
```PowerShell
93+
$params =@{
94+
Server="my-westus2-server.database.windows.net";
95+
Database="sql-license-usage";
96+
Cred=Get-Credential;
97+
}
98+
.\sql-license-usage.ps1 @params
8799
```
88100

89101
# Running the script using Cloud Shell
90102

91-
Use the following steps to calculate the SQL Server license usage:
103+
To run the script in the Cloud Shell, use the following steps:
92104

93105
1. Launch the [Cloud Shell](https://shell.azure.com/). For details, read [PowerShell in Cloud Shell](https://aka.ms/pscloudshell/docs).
94106

95107
2. Upload the script to the shell using the following command:
96108

97109
```console
98-
curl https://raw.githubusercontent.com/microsoft/sql-server-samples/master/samples/manage/azure-hybrid-benefit/sql-license-usage.ps1 -o sql-license-usage.ps1
110+
curl https://raw.githubusercontent.com/microsoft/sql-server-samples/master/samples/manage/azure-hybrid-benefit/sql-license-usage.ps1 -o sql-license-usage.ps1
99111
```
100112

101113
3. Run the script with a set of parameters that reflect your desired configuration.
102114

103115
```console
104-
./sql-license-usage.ps1 <parameters>
116+
./sql-license-usage.ps1 <parameters>
105117
```
106118

107119
> [!NOTE]
108120
> - To paste the commands into the shell, use `Ctrl-Shift-V` on Windows or `Cmd-v` on MacOS.
109121
> - The `curl` command will copy the script directly to the home folder associated with your Cloud Shell session.
110122

111-
# Tracking SQL license usage over time
123+
# Running the script as a Azure runbook
124+
125+
You can track your license utilization over time by running this script on schedule as a runbook. To set it up using Azure Portal, follow these steps.
112126

113-
You can track your license utilization over time by periodically running this script. To schedule automatic execution of the script, create a PowerShell runbook using an Azure Automation account. See the [Runbook tutorial](https://docs.microsoft.com/en-us/azure/automation/learn/automation-tutorial-runbook-textual-powershell) for the details of how to create a PowerShell runbook. Because the script accesses the resources across multiple subscriptions, the runbook must be able to authenticate using the Run As account that was automatically created when you created your Automation account. The logic required for the Runbooks is part of the script.
127+
1. Open a command shell on your device and run this command. It will copy the script to your local folder.
128+
```console
129+
curl https://raw.githubusercontent.com/microsoft/sql-server-samples/master/samples/manage/azure-hybrid-benefit/sql-license-usage.ps1 -o sql-license-usage.ps1
130+
```
131+
2. [Create a new automation account](https://ms.portal.azure.com/#create/Microsoft.AutomationAccount) or open an existing one.
132+
1. Select *Rus as accounts* in the **Account Settings** group, open the automatically created *Azure Run As Account* and note or copy the Display Name property. You must add this user to all the subscriptions you wish to scan with the *Reader* access role. See [Role assignment portal](https://docs.microsoft.com/en-us/azure/role-based-access-control/role-assignments-portal) for the instructions about role assignments.
133+
1. Select *Credentials* in the **Shared resources** group and create a credential object with the database username and password. The script will use these to connect to the specified database to save the license utilization data.
134+
1. Select *Modules* in the **Shared resources** group and make sure your automation account have the following PowerShell modules installed. If not, add them from the Gallery.
135+
- Az.Accounts
136+
- Az.Compute
137+
- Az.DataFactory
138+
- Az.Resources
139+
- Az.Sql
140+
- Az.SqlVirtualMachine
141+
1. Select *Runbooks* in the **Process automation** group and click on *Import a runbook*, select the file you downloaded in Step 1 and click **Create**.
142+
1. When import is completed, click the *Publish* button.
143+
1. From the runbook blade, click on the *Link to schedule* button and select an existing schedule or create a new one with the desired frequency of runs and the expiration time.
144+
1. Click on *Parameters and run settings* and specify the following parameters:
145+
- SUBID. Put in a subscription ID or leave it blank if you want to scan all the subscriptions the *Azure Run As Account* has been given access to in Step 3.
146+
- SERVER. Put in the SQL Server connection endpoint (e.g. my-westus2-sql-server.database.windows.net)
147+
- CRED. Put in the name of the credential object you created in Step 4.
148+
- DATABASE. Put in the database name where you want to save the license utilization data.
149+
- USEINRUNBOOKS. Select True to activate the logic that authenticates the runbook using the *Azure Run As Account*.
150+
1. Click **OK** to link to the schedule and **OK** again to create the job.
151+
152+
For more information about the runbooks, see the [Runbook tutorial](https://docs.microsoft.com/en-us/azure/automation/learn/automation-tutorial-runbook-textual-powershell)
114153

115154
>[!IMPORTANT]
116-
> - When running the script as a runbook, use a database to ensure that the results can be analyzed outside of the runbook.
117-
> - You must specify a *-UseInRunbook* switch to ensure that the runbook is authenticated using the Run As account.
155+
> When running the script as a runbook, it is necessary to save the data in a database so that the results could be analyzed outside of the runbook.

0 commit comments

Comments
 (0)