diff --git a/python/rpdk/python/codegen.py b/python/rpdk/python/codegen.py
index f5c49cf..60174aa 100644
--- a/python/rpdk/python/codegen.py
+++ b/python/rpdk/python/codegen.py
@@ -334,14 +334,24 @@ class Python36LanguagePlugin(LanguagePlugin):
 
         LOG.warning("Starting pip build.")
         try:
-            completed_proc = subprocess_run(  # nosec
-                command,
-                stdout=PIPE,
-                stderr=PIPE,
-                cwd=base_path,
-                check=True,
-                shell=True,
-            )
+            # On windows run pip command through the default shell (CMD)
+            if os.name == "nt":
+                completed_proc = subprocess_run(  # nosec
+                    command,
+                    stdout=PIPE,
+                    stderr=PIPE,
+                    cwd=base_path,
+                    check=True,
+                    shell=True,
+                )
+            else:
+                completed_proc = subprocess_run(  # nosec
+                    command,
+                    stdout=PIPE,
+                    stderr=PIPE,
+                    cwd=base_path,
+                    check=True,
+                )
             LOG.warning("pip build finished.")
         except (FileNotFoundError, CalledProcessError) as e:
             raise DownstreamError("pip build failed") from e
diff --git a/src/cloudformation_cli_python_lib/resource.py b/src/cloudformation_cli_python_lib/resource.py
index bf7ba30..bfc9384 100644
--- a/src/cloudformation_cli_python_lib/resource.py
+++ b/src/cloudformation_cli_python_lib/resource.py
@@ -164,9 +164,13 @@ class Resource:
         try:
             return UnmodelledRequest(
                 clientRequestToken=request.bearerToken,
-                desiredResourceState=request.requestData.resourceProperties,
+                desiredResourceState=request.requestData.resourceProperties
+                if request.requestData.resourceProperties
+                else {},
                 previousResourceState=request.requestData.previousResourceProperties,
-                desiredResourceTags=request.requestData.stackTags,
+                desiredResourceTags=request.requestData.stackTags
+                if request.requestData.stackTags
+                else {},
                 previousResourceTags=request.requestData.previousStackTags,
                 systemTags=request.requestData.systemTags,
                 previousSystemTags=request.requestData.previousSystemTags,

diff --git a/tests/plugin/codegen_test.py b/tests/plugin/codegen_test.py
index a36d04b..aa64261 100644
--- a/tests/plugin/codegen_test.py
+++ b/tests/plugin/codegen_test.py
@@ -416,6 +416,43 @@ def test__build_pip(plugin):
     mock_pip.assert_called_once_with(sentinel.base_path)
 
 
+def test__build_pip_posix(plugin):
+    patch_os_name = patch("rpdk.python.codegen.os.name", "posix")
+    patch_subproc = patch("rpdk.python.codegen.subprocess_run")
+
+    # Path must be set outside simulated os.name
+    temppath = Path(str(sentinel.base_path))
+    with patch_os_name, patch_subproc as mock_subproc:
+        plugin._pip_build(temppath)
+
+    mock_subproc.assert_called_once_with(
+        plugin._make_pip_command(temppath),
+        stdout=ANY,
+        stderr=ANY,
+        cwd=temppath,
+        check=ANY,
+    )
+
+
+def test__build_pip_windows(plugin):
+    patch_os_name = patch("rpdk.python.codegen.os.name", "nt")
+    patch_subproc = patch("rpdk.python.codegen.subprocess_run")
+
+    # Path must be set outside simulated os.name
+    temppath = Path(str(sentinel.base_path))
+    with patch_os_name, patch_subproc as mock_subproc:
+        plugin._pip_build(temppath)
+
+    mock_subproc.assert_called_once_with(
+        plugin._make_pip_command(temppath),
+        stdout=ANY,
+        stderr=ANY,
+        cwd=temppath,
+        check=ANY,
+        shell=True,
+    )
+
+
 def test__build_docker(plugin):
     plugin._use_docker = True
 

If a resource is created without Properties, request.desiredResourceState is None
This is not technically against the type annotations, but it would be nice if this wasn't the case.

Some snippets to test this with:

Schema:
```json
{
    "properties": {
        "Identifier": {"type": "string"},
    },   
    "required": [],
    "readOnlyProperties": ["/properties/Identifier"],
    "primaryIdentifier": ["/properties/Identifier"],
}
```

handlers.py inside of the create handler
```python
# this fails with `AttributeError: 'NoneType' object has no attribute 'Identifier'`
model = request.desiredResourceState
model.Identifier = identifier_utils.generate_resource_identifier(
    request.stackId, request.logicalResourceIdentifier,
    request.clientRequestToken, 255
)

# this works
model = request.desiredResourceState if request.desiredResourceState else ResourceModel(Identifier=None)
model.Identifier = identifier_utils.generate_resource_identifier(
    request.stackId, request.logicalResourceIdentifier,
    request.clientRequestToken, 255
)
```

I believe this can be solved by changing [this code in resource.py](https://github.com/aws-cloudformation/cloudformation-cli-python-plugin/blob/master/src/cloudformation_cli_python_lib/resource.py#L167)

from
```python
return UnmodelledRequest(
    # [...]
    desiredResourceState=request.requestData.resourceProperties,
     # [...]
 ).to_modelled(self._model_cls, self._type_configuration_model_cls)
```
to
```python
return UnmodelledRequest(
    # [...]
    desiredResourceState=request.requestData.resourceProperties if request.requestData.resourceProperties else {},
     # [...]
 ).to_modelled(self._model_cls, self._type_configuration_model_cls)
```

This probably also applies to previousResourceState and maybe even to the Tag-related properties
tests/plugin/codegen_test.py::test__build_pip_posix
tests/plugin/codegen_test.py::test_validate_no[y-True] tests/plugin/codegen_test.py::test_validate_no[Y-True] tests/plugin/codegen_test.py::test_validate_no[yes-True] tests/plugin/codegen_test.py::test_validate_no[Yes-True] tests/plugin/codegen_test.py::test_validate_no[YES-True] tests/plugin/codegen_test.py::test_validate_no[asdf-True] tests/plugin/codegen_test.py::test_validate_no[no-False] tests/plugin/codegen_test.py::test_validate_no[No-False0] tests/plugin/codegen_test.py::test_validate_no[No-False1] tests/plugin/codegen_test.py::test_validate_no[n-False] tests/plugin/codegen_test.py::test_validate_no[N-False] tests/plugin/codegen_test.py::test__remove_build_artifacts_file_found tests/plugin/codegen_test.py::test__remove_build_artifacts_file_not_found tests/plugin/codegen_test.py::test_initialize_resource tests/plugin/codegen_test.py::test_initialize_hook tests/plugin/codegen_test.py::test_package_resource_pip tests/plugin/codegen_test.py::test__pip_build_executable_not_found tests/plugin/codegen_test.py::test__pip_build_called_process_error tests/plugin/codegen_test.py::test__build_pip tests/plugin/codegen_test.py::test__build_pip_windows tests/plugin/codegen_test.py::test__build_docker tests/plugin/codegen_test.py::test__build_docker_posix tests/plugin/codegen_test.py::test__build_docker_windows tests/plugin/codegen_test.py::test__build_docker_no_euid tests/plugin/codegen_test.py::test__docker_build_good_path tests/plugin/codegen_test.py::test_get_plugin_information tests/plugin/codegen_test.py::test__docker_build_bad_path[<lambda>0] tests/plugin/codegen_test.py::test__docker_build_bad_path[ImageLoadError] tests/plugin/codegen_test.py::test__docker_build_bad_path[<lambda>1] tests/plugin/codegen_test.py::test__docker_build_bad_path[<lambda>2]